@qnroa/qtype 0.2.0 → 0.2.1

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/CHANGELOG.md CHANGED
@@ -13,6 +13,32 @@ can land in any minor bump (`0.x.0`).
13
13
 
14
14
  ## [Unreleased]
15
15
 
16
+ ## [0.2.1] — 2026-09-01
17
+
18
+ Discoverability pass for `qtype config`. Users no longer have to grep
19
+ the source (or the wiki) to find out what keys they can set.
20
+
21
+ ### Added
22
+ - **`qtype config --help` now lists every configurable key** at the
23
+ bottom of the help output — one line per key with its default, scope,
24
+ description, and enum options where applicable. Same source of truth
25
+ as the actual schema, so it stays honest.
26
+ - **`qtype config list --all`** — verbose per-key view: current value
27
+ (or default if unset), source (which file / default), scope, and
28
+ enum options. Complements `list` (only shows keys the user has
29
+ actually set).
30
+ - **`SchemaEntry.description` + `SchemaEntry.options`** fields, both
31
+ optional. Populated for every currently-registered key so the two
32
+ new help surfaces have something to show.
33
+ - **`CommandModule.afterHelp`** hook — commands can append reference
34
+ material after the standard help sections. `config` uses it; other
35
+ commands can add their own without touching the registry.
36
+
37
+ ### Changed
38
+ - Cleaned up in-line doc comments in the schema files (they've been
39
+ moved into the `description` field where possible, so they're
40
+ reachable at runtime).
41
+
16
42
  ## [0.2.0] — 2026-08-31
17
43
 
18
44
  Substantial rework of the typing page. The screen-flow is now a real
package/CHANGELOG.zh.md CHANGED
@@ -12,6 +12,27 @@ English: [CHANGELOG.md](https://www.npmjs.com/package/@qnroa/qtype?activeTab=cod
12
12
 
13
13
  ## [Unreleased]
14
14
 
15
+ ## [0.2.1] — 2026-09-01
16
+
17
+ `qtype config` 的可发现性升级。用户不再需要翻源码或 wiki 才知道能设
18
+ 置哪些 key。
19
+
20
+ ### 新增
21
+ - **`qtype config --help` 现在会在底部列出所有可配置的 key**,一行一个,
22
+ 含默认值、作用域、描述、枚举选项(如果有)。数据源就是 schema 本身,
23
+ 不会脱节。
24
+ - **`qtype config list --all`** —— 详版:每个 key 显示当前值(或未设置
25
+ 时的默认)、来源(哪个文件 / 默认)、作用域、枚举选项。和 `list`(只
26
+ 显示用户设过的)互补。
27
+ - **`SchemaEntry.description` + `SchemaEntry.options`** 两个可选字段。
28
+ 现在每个已注册 key 都填了,给上面两个新的 help 出口提供内容。
29
+ - **`CommandModule.afterHelp` 钩子** —— 命令可以在标准 help 段落后追加
30
+ 参考内容。`config` 用它,其它命令想加也行,不用改 registry。
31
+
32
+ ### 变更
33
+ - 清理了 schema 文件里的行内文档注释(能放进 `description` 的都挪进
34
+ 去了,这样运行时就能读到)。
35
+
15
36
  ## [0.2.0] — 2026-08-31
16
37
 
17
38
  打字页面的整体架构重写。屏幕流程改成了真正的有限状态机(xstate),
@@ -178,6 +178,12 @@ export async function configUnsetAction(key, opts) {
178
178
  /** `qtype config list [--global|--local] [--show-origin]` */
179
179
  export async function configListAction(opts) {
180
180
  const scope = pickScope(opts);
181
+ // --all: enumerate every schema-known key, filling in defaults for
182
+ // ones the user hasn't set. Useful for discovering what can be
183
+ // configured.
184
+ if (opts.all) {
185
+ return listAllKnown(scope);
186
+ }
181
187
  const userEntries = scope === 'repo' ? [] : await userKv.list();
182
188
  const repoEntries = scope === 'user' ? [] : (await repoKv.available()) ? await repoKv.list() : [];
183
189
  const rows = [];
@@ -220,6 +226,68 @@ export async function configListAction(opts) {
220
226
  // ═══════════════════════════════════════════════════════════════
221
227
  // helpers
222
228
  // ═══════════════════════════════════════════════════════════════
229
+ /**
230
+ * List every key known to the schema in the given scope (all if scope
231
+ * is undefined). For each key: current value + source, or default +
232
+ * `(default)` marker if unset, plus type / options / description.
233
+ */
234
+ async function listAllKnown(scope) {
235
+ const rows = [];
236
+ const seen = new Set();
237
+ if (scope !== 'repo') {
238
+ for (const k of userKv.knownKeys()) {
239
+ if (seen.has(k))
240
+ continue;
241
+ seen.add(k);
242
+ rows.push({ key: k, kv: userKv, scope: 'user' });
243
+ }
244
+ }
245
+ if (scope !== 'user') {
246
+ for (const k of repoKv.knownKeys()) {
247
+ if (seen.has(k))
248
+ continue;
249
+ seen.add(k);
250
+ rows.push({ key: k, kv: repoKv, scope: 'repo' });
251
+ }
252
+ }
253
+ rows.sort((a, b) => a.key.localeCompare(b.key));
254
+ const repoAvailable = scope === 'user' ? false : await repoKv.available();
255
+ for (const r of rows) {
256
+ const entry = r.kv.getSchema(r.key);
257
+ // Prefer the stored value (from user or repo scope); fall back to
258
+ // the schema default. `get` returns default when unset, so guard
259
+ // with `has` first to know whether the value is user-set.
260
+ let currentDisplay = '';
261
+ let sourceLabel = '';
262
+ const canRead = r.scope === 'user' || repoAvailable;
263
+ if (canRead && (await r.kv.has(r.key))) {
264
+ const raw = await r.kv.get(r.key);
265
+ currentDisplay = formatValue(raw);
266
+ sourceLabel = `${r.scope}:${r.kv.origin}`;
267
+ }
268
+ else {
269
+ currentDisplay = formatValue(entry.default);
270
+ sourceLabel = 'default';
271
+ }
272
+ const parts = [`${r.key}=${currentDisplay}`];
273
+ if (entry.description)
274
+ parts.push(dim(entry.description));
275
+ console.log(parts.join(' '));
276
+ const meta = [];
277
+ if (entry.options && entry.options.length > 0) {
278
+ meta.push(`options: ${entry.options.join(' | ')}`);
279
+ }
280
+ if (entry.default !== undefined && sourceLabel === 'default') {
281
+ // already shown as current; keep meta uncluttered
282
+ }
283
+ else if (entry.default !== undefined) {
284
+ meta.push(`default: ${formatValue(entry.default)}`);
285
+ }
286
+ meta.push(`scope: ${r.scope}`);
287
+ meta.push(`source: ${sourceLabel}`);
288
+ console.log(' ' + dim(meta.join(' · ')));
289
+ }
290
+ }
223
291
  /** Format a value as a single-line string. Objects / arrays use JSON. */
224
292
  function formatValue(v) {
225
293
  if (v == null)
@@ -7,8 +7,10 @@ export const messages = {
7
7
  'config.opt.global': '操作 user 层(~/.config/qtype/config.json)',
8
8
  'config.opt.local': '操作 repo 层(<repo>/.qtype/config.json)',
9
9
  'config.opt.showOrigin': '显示配置项来源(文件路径 / 哪一层)',
10
+ 'config.opt.all': '列出所有可配置项(含 schema 里未设置的默认值)',
10
11
  'config.example.setLang': '设置 CLI 语言',
11
12
  'config.example.list': '列出所有生效配置',
13
+ 'config.list.example.all': '列出所有可配置项及默认值',
12
14
  'config.get.summary': '读配置',
13
15
  'config.get.description': '读取指定 key 的值(默认合并两层;key 不存在 exit 1)',
14
16
  'config.get.example.basic': '读 CLI 语言偏好',
@@ -29,6 +31,8 @@ export const messages = {
29
31
  'config.list.example.global': '只看 user 层',
30
32
  'config.list.msg.empty': '配置为空',
31
33
  'config.list.msg.emptyScoped': '配置为空 ({scope})',
34
+ 'config.help.keysHeader': '可配置项:',
35
+ 'config.help.keysFooter': '用 `qtype config set <key> <value>` 修改;`qtype config list --all` 查看完整状态。',
32
36
  },
33
37
  'en-US': {
34
38
  'config.summary': 'Manage config',
@@ -38,8 +42,10 @@ export const messages = {
38
42
  'config.opt.global': 'Operate on user scope (~/.config/qtype/config.json)',
39
43
  'config.opt.local': 'Operate on repo scope (<repo>/.qtype/config.json)',
40
44
  'config.opt.showOrigin': 'Show where each entry comes from (file path and scope)',
45
+ 'config.opt.all': 'List every configurable key, including schema defaults for unset keys',
41
46
  'config.example.setLang': 'Set CLI language',
42
47
  'config.example.list': 'List all effective config',
48
+ 'config.list.example.all': 'List every configurable key with defaults',
43
49
  'config.get.summary': 'Get value',
44
50
  'config.get.description': 'Get value for a key (merged by default; exit 1 if key not set)',
45
51
  'config.get.example.basic': 'Read CLI language preference',
@@ -60,5 +66,7 @@ export const messages = {
60
66
  'config.list.example.global': 'Only user scope',
61
67
  'config.list.msg.empty': 'Config is empty',
62
68
  'config.list.msg.emptyScoped': 'Config is empty ({scope})',
69
+ 'config.help.keysHeader': 'Available keys:',
70
+ 'config.help.keysFooter': 'Use `qtype config set <key> <value>` to change one; `qtype config list --all` to see the full state.',
63
71
  },
64
72
  };
@@ -1,5 +1,7 @@
1
1
  import { t } from '../../i18n/index.js';
2
2
  import { messages } from './i18n.js';
3
+ import { userKv, repoKv } from '../../bootstrap.js';
4
+ import { bold, dim } from '../../utils/output.js';
3
5
  import { configGetAction, configSetAction, configUnsetAction, configListAction, } from './action.js';
4
6
  /** Shared --global / --local / --show-origin options. */
5
7
  const scopeOptions = [
@@ -52,13 +54,59 @@ const listCmd = {
52
54
  options: [
53
55
  ...scopeOptions,
54
56
  { flags: '--show-origin', describe: () => t('config.opt.showOrigin') },
57
+ { flags: '--all', describe: () => t('config.opt.all') },
55
58
  ],
56
59
  examples: () => [
57
60
  { command: 'qtype config list', describe: () => t('config.list.example.merged') },
58
61
  { command: 'qtype config list --global', describe: () => t('config.list.example.global') },
62
+ { command: 'qtype config list --all', describe: () => t('config.list.example.all') },
59
63
  ],
60
64
  action: async (opts) => configListAction(opts),
61
65
  };
66
+ /**
67
+ * Render every configurable key (from both user and repo schemas)
68
+ * as a `key = <default> — description` list. Used by `qtype
69
+ * config --help` so users can discover what can be tuned without
70
+ * hunting through docs.
71
+ */
72
+ function renderAvailableKeys() {
73
+ const rows = [];
74
+ const seen = new Set();
75
+ for (const k of userKv.knownKeys()) {
76
+ if (seen.has(k))
77
+ continue;
78
+ seen.add(k);
79
+ const e = userKv.getSchema(k);
80
+ rows.push({ key: k, scope: 'user', default: e.default, description: e.description, options: e.options });
81
+ }
82
+ for (const k of repoKv.knownKeys()) {
83
+ if (seen.has(k))
84
+ continue;
85
+ seen.add(k);
86
+ const e = repoKv.getSchema(k);
87
+ rows.push({ key: k, scope: 'repo', default: e.default, description: e.description, options: e.options });
88
+ }
89
+ rows.sort((a, b) => a.key.localeCompare(b.key));
90
+ const fmtDefault = (v) => {
91
+ if (v === undefined)
92
+ return '(no default)';
93
+ if (typeof v === 'string')
94
+ return v || '""';
95
+ return JSON.stringify(v);
96
+ };
97
+ const lines = [bold(t('config.help.keysHeader'))];
98
+ for (const r of rows) {
99
+ lines.push(` ${r.key} ${dim('=')} ${fmtDefault(r.default)} ${dim(`(${r.scope})`)}`);
100
+ if (r.description)
101
+ lines.push(` ${dim(r.description)}`);
102
+ if (r.options && r.options.length > 0) {
103
+ lines.push(` ${dim(`options: ${r.options.join(' | ')}`)}`);
104
+ }
105
+ }
106
+ lines.push('');
107
+ lines.push(dim(t('config.help.keysFooter')));
108
+ return lines.join('\n');
109
+ }
62
110
  export const configCmd = {
63
111
  name: 'config',
64
112
  messages,
@@ -67,6 +115,8 @@ export const configCmd = {
67
115
  examples: () => [
68
116
  { command: 'qtype config set cli.lang zh', describe: () => t('config.example.setLang') },
69
117
  { command: 'qtype config list', describe: () => t('config.example.list') },
118
+ { command: 'qtype config list --all', describe: () => t('config.list.example.all') },
70
119
  ],
120
+ afterHelp: () => renderAvailableKeys(),
71
121
  subcommands: [getCmd, setCmd, unsetCmd, listCmd],
72
122
  };
@@ -66,6 +66,12 @@ export function applyHelpMetadata(cmd, mod) {
66
66
  if (mod.seeAlso && mod.seeAlso.length > 0) {
67
67
  cmd.addHelpText('after', renderSeeAlso(mod.seeAlso));
68
68
  }
69
+ // Free-form afterHelp — printed last, useful for reference lists.
70
+ if (mod.afterHelp) {
71
+ const extra = mod.afterHelp();
72
+ if (extra && extra.trim())
73
+ cmd.addHelpText('after', '\n' + extra);
74
+ }
69
75
  // Aliases
70
76
  if (mod.aliases && mod.aliases.length > 0) {
71
77
  for (const alias of mod.aliases)
@@ -5,48 +5,50 @@
5
5
  */
6
6
  import { enumValidator, boolValidator, positiveIntValidator, } from '../../store/index.js';
7
7
  export const bothSchema = {
8
- // Repo language. Drives:
9
- // • which template locale (examples/zh vs examples/en) new repos are
10
- // scaffolded from
11
- // • the web UI language — the reader is locked to repo.lang so the UI
12
- // matches the material's own language
13
- //
14
- // Values are BCP 47 codes (`zh-CN` / `en-US`); the short forms `zh` /
15
- // `en` are accepted for backwards compatibility with older `.qtype/
16
- // config.json` files and normalised at read time.
17
8
  'repo.lang': {
18
9
  validator: enumValidator(['zh-CN', 'en-US', 'zh', 'en']),
19
10
  default: 'en-US',
11
+ description: 'Repo (and its published web UI) language.',
12
+ options: ['zh-CN', 'en-US'],
20
13
  },
21
14
  'typing.theme': {
22
15
  validator: enumValidator(['mocha', 'latte']),
23
16
  default: 'mocha',
17
+ description: 'Web reader theme.',
18
+ options: ['mocha', 'latte'],
24
19
  },
25
20
  'typing.targetWpm': {
26
21
  validator: positiveIntValidator(),
22
+ description: 'Ghost-pacer target speed in WPM. 0 = disabled.',
27
23
  },
28
24
  'typing.tabBehavior': {
29
25
  validator: enumValidator(['reset', 'input', 'disabled']),
30
26
  default: 'reset',
27
+ description: 'What pressing Tab in the arena does.',
28
+ options: ['reset', 'input', 'disabled'],
31
29
  },
32
30
  'typing.hint': {
33
31
  validator: enumValidator(['none', 'ghost']),
34
32
  default: 'none',
33
+ description: 'Whether to render a faint ghost hint under the caret.',
34
+ options: ['none', 'ghost'],
35
35
  },
36
36
  'typing.showKeyboard': {
37
37
  validator: boolValidator(),
38
38
  default: true,
39
+ description: 'Show the on-screen keyboard beneath the arena.',
40
+ options: ['true', 'false'],
39
41
  },
40
42
  'typing.showHands': {
41
43
  validator: boolValidator(),
42
44
  default: true,
45
+ description: 'Show the hand overlay on the on-screen keyboard.',
46
+ options: ['true', 'false'],
43
47
  },
44
- // Mermaid pre-render mode. `prerender` (default) uses puppeteer at build
45
- // time to bake SVGs into dist/material/mermaid.json; `client` ships raw
46
- // ```mermaid fences and lets the browser render them; `off` treats mermaid
47
- // as plain code blocks.
48
48
  'publish.mermaid': {
49
49
  validator: enumValidator(['prerender', 'client', 'off']),
50
50
  default: 'prerender',
51
+ description: 'Mermaid diagram handling at `publish build` time.',
52
+ options: ['prerender', 'client', 'off'],
51
53
  },
52
54
  };
@@ -6,43 +6,35 @@ import { enumValidator, nonEmptyStringValidator, boolValidator, } from '../../st
6
6
  export const repoOnlySchema = {
7
7
  'repo.name': {
8
8
  validator: nonEmptyStringValidator(),
9
+ description: 'Repo display name (folder title, package.json name).',
9
10
  },
10
11
  // ── Password protection for `publish build` ─────────────
11
- // On/off toggle. When true, `publish build` reads the other three fields
12
- // and encrypts every material/*.md before writing to dist.
13
12
  'publish.password.enabled': {
14
13
  validator: boolValidator(),
15
14
  default: false,
15
+ description: 'Encrypt materials at `publish build` time.',
16
+ options: ['true', 'false'],
16
17
  },
17
- // Argon2id PHC-style hash of the plaintext password, used to verify the
18
- // password entered at build time. NOT the AES key — that's derived
19
- // separately via `publish.password.aesSalt`. Empty string when protection
20
- // is off; shape enforced by `publish password set` writing a well-formed
21
- // PHC string.
22
18
  'publish.password.hash': {
23
19
  validator: (v) => typeof v === 'string'
24
20
  ? null
25
21
  : { code: 'err.schema.nonEmptyString', fallback: 'must be a string' },
26
22
  default: '',
23
+ description: 'Argon2id PHC hash of the publish password (managed by `qtype publish password`).',
27
24
  },
28
- // Base64 salt used with argon2id (password → AES-256 key). Rotated only
29
- // when the user calls `publish password set` — stable across rebuilds so
30
- // the same password unlocks previously published sites.
31
25
  'publish.password.aesSalt': {
32
26
  validator: (v) => typeof v === 'string'
33
27
  ? null
34
28
  : { code: 'err.schema.nonEmptyString', fallback: 'must be a string' },
35
29
  default: '',
30
+ description: 'Base64 salt used to derive the AES key (managed by `qtype publish password`).',
36
31
  },
37
- // What to encrypt. `all` covers material/ + any future encrypted assets;
38
- // `material-only` limits encryption to material/*.md (same behavior in
39
- // v0 since qtype has no other content streams).
40
32
  'publish.password.scope': {
41
33
  validator: enumValidator(['all', 'material-only', 'selected']),
42
34
  default: 'all',
35
+ description: 'What to encrypt when password protection is on.',
36
+ options: ['all', 'material-only', 'selected'],
43
37
  },
44
- // When scope='selected', the list of file names (relative to material/)
45
- // to encrypt. Ignored otherwise.
46
38
  'publish.password.selected': {
47
39
  validator: (v) => Array.isArray(v) && v.every((x) => typeof x === 'string')
48
40
  ? null
@@ -51,5 +43,6 @@ export const repoOnlySchema = {
51
43
  fallback: 'must be an array of strings',
52
44
  },
53
45
  default: [],
46
+ description: 'File names to encrypt when scope is `selected` (JSON array).',
54
47
  },
55
48
  };
@@ -11,9 +11,13 @@ export const userOnlySchema = {
11
11
  'cli.lang': {
12
12
  validator: enumValidator(['zh-CN', 'en-US', 'zh', 'en']),
13
13
  default: 'en-US',
14
+ description: 'CLI display language.',
15
+ options: ['zh-CN', 'en-US'],
14
16
  },
15
17
  'cli.color': {
16
18
  validator: enumValidator(['always', 'never', 'auto']),
17
19
  default: 'auto',
20
+ description: 'Color output policy for CLI messages.',
21
+ options: ['always', 'never', 'auto'],
18
22
  },
19
23
  };
@@ -0,0 +1 @@
1
+ .qt-qi{position:relative;width:100%}.qt-qi__input{width:100%;height:var(--search-h);padding:0 var(--space-3);padding-right:2.4rem;border-radius:var(--radius);background:var(--qt-base);color:var(--qt-text);border:1px solid var(--qt-border);outline:none;font-family:inherit;font-size:var(--fs-ui);transition:border-color .12s ease}.qt-qi__input::placeholder{color:var(--qt-text-muted)}.qt-qi__input:focus{border-color:var(--qt-accent)}.qt-qi__kbd{position:absolute;right:8px;top:50%;transform:translateY(-50%);padding:.1em .5em;font-size:.72em;border-radius:3px;color:var(--qt-text-muted);background:var(--qt-mantle);border:1px solid var(--qt-border);font-family:var(--font-mono);pointer-events:none}.qt-qi__panel{position:absolute;top:calc(100% + 4px);left:0;right:0;max-height:60vh;overflow-y:auto;background:var(--qt-mantle);border:1px solid var(--qt-border);border-radius:var(--radius);box-shadow:0 12px 32px #00000052;padding:var(--space-1);z-index:40}.qt-qi__row{width:100%;display:flex;align-items:center;gap:10px;padding:8px 12px;min-height:var(--control-h);background:transparent;border:none;border-left:2px solid transparent;border-radius:4px;color:var(--qt-text);text-align:left;font-family:inherit;font-size:var(--fs-ui);cursor:pointer;transition:background .12s ease}.qt-qi__row.is-focused{background:var(--qt-surface-hover)}.qt-qi__row.is-active{border-left-color:var(--qt-accent);font-weight:600}.qt-qi__row.is-disabled{opacity:.5;cursor:not-allowed}.qt-qi__body{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.qt-qi__label{color:var(--qt-text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.qt-qi__detail{color:var(--qt-text-muted);font-size:var(--fs-caption);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.qt-qi__desc{color:var(--qt-text-muted);font-family:var(--font-mono);font-size:var(--fs-caption);flex-shrink:0}.qt-header{height:var(--header-h);display:grid;align-items:center;padding:0 max(var(--gutter),env(safe-area-inset-left));background:var(--qt-mantle);border-bottom:1px solid var(--qt-border);color:var(--qt-text);position:sticky;top:0;z-index:30}.qt-header--ml{grid-template-columns:minmax(0,1fr) minmax(clamp(120px,30vw,240px),2fr) minmax(0,1fr);gap:var(--space-2)}.qt-header--s{grid-template-columns:auto minmax(0,1fr) auto;gap:8px}.qt-brand{display:flex;align-items:center;gap:var(--space-2);background:transparent;border:none;padding:0;cursor:pointer;color:inherit;font-family:inherit;transition:color .12s ease}.qt-brand:hover .qt-brand__name{color:var(--qt-accent)}.qt-brand:focus-visible{outline:none}.qt-brand:focus-visible .qt-brand__name{color:var(--qt-accent)}.qt-brand__logo{display:block;width:28px;height:28px;flex-shrink:0}.qt-brand__name{font-size:var(--fs-title);font-weight:600;color:var(--qt-text);letter-spacing:.01em}.qt-header--s .qt-brand__name{display:none}.qt-header-search{width:100%}.qt-header-right{display:flex;align-items:center;gap:var(--space-2);justify-self:end}.qt-header-count{color:var(--qt-text-muted);font-family:var(--font-mono);font-size:var(--fs-caption)}.qt-header-stats{display:flex;align-items:center;gap:10px;justify-self:end}.qt-header-count-pct{color:var(--qt-green)}.qt-header-pct{color:var(--qt-green);font-family:var(--font-mono);font-size:var(--fs-caption);font-weight:600;min-width:2.8em;text-align:right}.qt-header-bar{width:90px;height:5px;background:var(--qt-border);border-radius:3px;overflow:hidden;flex-shrink:0}.qt-header-bar__fill{height:100%;width:var(--qt-progress, 0%);background:var(--qt-green);transition:width .22s ease}.qt-header{position:sticky;top:0;z-index:30}.qt-footer{position:relative;height:26px;display:flex;align-items:center;gap:var(--space-3);padding:0 max(var(--gutter),env(safe-area-inset-left));background:var(--qt-mantle);border-top:1px solid var(--qt-border);color:var(--qt-text-muted);font-size:var(--fs-caption);font-family:var(--font-ui)}.qt-footer__left{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.qt-footer__center{position:absolute;left:50%;transform:translate(-50%);display:flex;align-items:center;color:var(--qt-text-muted);font-family:var(--font-mono)}.qt-footer__right{display:flex;align-items:center;gap:4px;flex-shrink:0}.qt-footer__stat{width:22px;height:22px;padding:0;background:transparent;border:none;color:var(--qt-text-muted);font-size:.85rem;border-radius:4px;cursor:pointer;transition:background .12s ease,color .12s ease;display:inline-flex;align-items:center;justify-content:center}.qt-footer__icon{display:block;vertical-align:middle}.qt-footer__stat:hover:not(:disabled){background:color-mix(in srgb,var(--qt-text) 8%,transparent);color:var(--qt-text)}.qt-footer__stat:disabled{opacity:.4;cursor:not-allowed}.qt-footer__stat.is-off{opacity:.55}@media (max-width: 640px){.qt-footer__left{display:none}}.qt-combobox{display:inline-flex;flex-direction:column;gap:var(--space-2);min-width:120px}.qt-combobox__trigger{display:inline-flex;align-items:center;justify-content:space-between;gap:8px;height:var(--control-h);padding:0 12px;min-width:120px;background:var(--qt-mantle);border:1px solid var(--qt-border);border-radius:var(--radius);color:var(--qt-text-muted);font-family:inherit;font-size:var(--fs-ui);cursor:pointer;transition:background .12s ease,border-color .12s ease,color .12s ease}.qt-combobox__trigger:hover{border-color:color-mix(in srgb,var(--qt-text) 20%,var(--qt-border))}.qt-combobox__trigger[data-state=open]{border-color:var(--qt-accent)}.qt-combobox__trigger.has-value{color:var(--qt-text)}.qt-combobox__label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.qt-combobox__chev{color:var(--qt-text-muted);flex-shrink:0}.qt-combobox__panel{min-width:var(--radix-popover-trigger-width);width:fit-content;max-width:min(360px,calc(100vw - 24px));background:var(--qt-mantle);border:1px solid var(--qt-border);border-radius:8px;box-shadow:0 8px 24px #00000040;overflow:hidden;z-index:60;animation:qt-combobox-in .1s ease-out}@keyframes qt-combobox-in{0%{opacity:0;transform:translateY(-2px)}to{opacity:1;transform:translateY(0)}}.qt-combobox__cmd{display:flex;flex-direction:column}.qt-combobox__searchwrap{padding:0 var(--space-3);border-bottom:1px solid var(--qt-border)}.qt-combobox__search{width:100%;height:32px;padding:0;background:transparent;border:none;color:var(--qt-text);font-family:inherit;font-size:13px;outline:none}.qt-combobox__search::placeholder{color:var(--qt-text-muted)}.qt-combobox__list{max-height:280px;overflow-y:auto;padding:4px 0}.qt-combobox__empty{padding:20px 12px;text-align:center;color:var(--qt-text-muted);font-size:12px}.qt-combobox__group [cmdk-group-heading]{padding:8px var(--space-3) 4px;color:var(--qt-text-muted);font-size:10.5px;font-weight:500;letter-spacing:.08em;text-transform:uppercase}.qt-combobox__item{display:flex;align-items:center;gap:8px;padding:6px var(--space-3);color:var(--qt-text);font-size:13px;cursor:pointer;-webkit-user-select:none;user-select:none}.qt-combobox__item[data-selected=true],.qt-combobox__item[aria-selected=true]{background:color-mix(in srgb,var(--qt-text) 6%,transparent)}.qt-combobox__check{width:14px;color:transparent;font-size:12px;flex-shrink:0;text-align:center}.qt-combobox__check.is-on{color:var(--qt-accent)}.qt-combobox__item-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.qt-combobox__footer{display:flex;align-items:center;justify-content:space-between;padding:6px var(--space-3);border-top:1px solid var(--qt-border);gap:8px}.qt-combobox__footer-count{color:var(--qt-text-muted);font-size:11.5px;font-family:var(--font-mono)}.qt-combobox__footer-clear{background:transparent;border:none;padding:2px 8px;color:var(--qt-text-muted);font-family:inherit;font-size:12px;cursor:pointer;border-radius:4px;transition:color .12s ease,background .12s ease}.qt-combobox__footer-clear:hover:not(:disabled){color:var(--qt-red, #f38ba8);background:color-mix(in srgb,var(--qt-text) 6%,transparent)}.qt-combobox__footer-clear:disabled{opacity:.4;cursor:not-allowed}.qt-combobox__chips{display:flex;flex-wrap:wrap;gap:6px}.qt-combobox__chip{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;background:color-mix(in srgb,var(--qt-accent) 14%,transparent);color:var(--qt-accent);border:1px solid transparent;border-radius:6px;font-size:11.5px;letter-spacing:.02em}.qt-combobox__chip-x{background:transparent;border:none;padding:0 2px;color:var(--qt-text-muted);font-size:14px;line-height:1;cursor:pointer;border-radius:3px}.qt-combobox__chip-x:hover{color:var(--qt-text);background:color-mix(in srgb,var(--qt-text) 8%,transparent)}.qt-toolbar{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3);padding:0;position:relative;z-index:15}.qt-toolbar__filters{display:flex;align-items:center;gap:var(--space-2);flex-wrap:wrap}.qt-toolbar--selection{align-items:center;min-height:var(--control-h);gap:6px}.qt-selbar__count{flex:0 0 auto;color:var(--qt-text-muted);font-family:var(--font-mono);font-size:var(--fs-caption);padding:0 var(--space-2)}.qt-selbar__count b{color:var(--qt-accent);font-weight:600}.qt-selbar__spacer{flex:1}.qt-selbar__btn{background:transparent;border:1px solid var(--qt-border);color:var(--qt-text-muted);padding:0 12px;height:var(--control-h);border-radius:var(--radius);font-family:inherit;font-size:var(--fs-ui);cursor:pointer;transition:color .12s ease,border-color .12s ease,background .12s ease}.qt-selbar__btn:hover:not(:disabled){color:var(--qt-text);border-color:color-mix(in srgb,var(--qt-accent) 40%,var(--qt-border))}.qt-selbar__btn--danger:hover:not(:disabled){color:var(--qt-red);border-color:color-mix(in srgb,var(--qt-red) 50%,var(--qt-border));background:color-mix(in srgb,var(--qt-red) 10%,transparent)}.qt-selbar__btn:disabled{opacity:.4;cursor:not-allowed}.qt-right-stack{flex-shrink:0;display:flex;align-items:center;gap:6px;height:var(--control-h)}.qt-select-btn{display:inline-flex;align-items:center;justify-content:center;width:var(--icon-btn);height:var(--icon-btn);padding:0;background:transparent;border:1px solid var(--qt-border);border-radius:var(--radius);color:var(--qt-text-muted);cursor:pointer;transition:color .12s ease,border-color .12s ease,background .12s ease}.qt-select-btn:hover{color:var(--qt-accent);border-color:var(--qt-accent);background:var(--qt-surface-hover)}.qt-select-btn.is-active{color:var(--qt-accent);border-color:var(--qt-accent);background:color-mix(in srgb,var(--qt-accent) 12%,transparent)}.qt-chip-hidden-badge{display:inline-flex;align-items:center;height:var(--control-h);padding:0 8px;border-radius:9999px;background:color-mix(in srgb,var(--qt-accent) 18%,transparent);color:var(--qt-accent);font-family:var(--font-mono);font-size:var(--fs-caption);line-height:1;border:1px solid transparent;flex-shrink:0;-webkit-user-select:none;user-select:none}.qt-tag-clickcatcher{position:fixed;top:0;right:0;bottom:0;left:0;background:transparent;z-index:10}.qt-chips{flex:1;min-width:0;position:relative;transition:background .16s ease-out,box-shadow .16s ease-out,padding .16s ease-out,border-color .16s ease-out;border-radius:var(--radius);border:1px solid transparent;overflow:hidden}.qt-chips.is-expanded{z-index:20;overflow:visible}.qt-chips__row{display:flex;align-items:center;gap:6px;flex-wrap:nowrap;transition:flex-wrap 0s}.qt-chips__row.is-expanded{flex-wrap:wrap}.qt-chips__measure{position:absolute;visibility:hidden;pointer-events:none;top:0;left:0;width:max-content;max-width:none;display:flex;gap:6px;white-space:nowrap}.qt-chip{background:transparent;border:1px solid var(--qt-border);color:var(--qt-text-muted);padding:0 12px;height:var(--control-h);border-radius:9999px;font-family:inherit;font-size:var(--fs-ui);line-height:1;white-space:nowrap;cursor:pointer;transition:background .12s ease,color .12s ease,border-color .12s ease;display:inline-flex;align-items:center;gap:4px}.qt-chip__icon{flex-shrink:0;display:block}.qt-chip:hover{color:var(--qt-text);border-color:color-mix(in srgb,var(--qt-accent) 40%,var(--qt-border))}.qt-chip.is-active{background:color-mix(in srgb,var(--qt-accent) 18%,transparent);color:var(--qt-accent);border-color:var(--qt-accent)}.qt-chip--more{color:var(--qt-text-muted)}.qt-chip--more.is-open{color:var(--qt-text);border-color:var(--qt-accent);background:var(--qt-surface-hover)}.qt-chip--more.has-selected{color:var(--qt-accent);border-color:var(--qt-accent)}.qt-chip-more__badge{display:inline-flex;align-items:center;justify-content:center;min-width:16px;height:16px;padding:0 5px;border-radius:8px;background:var(--qt-accent);color:#fff;font-size:10px;font-family:var(--font-mono)}.qt-chip--reset{color:var(--qt-text-muted);padding:0 10px;gap:6px}.qt-chip--reset:hover{color:var(--qt-red);border-color:color-mix(in srgb,var(--qt-red) 50%,var(--qt-border));background:color-mix(in srgb,var(--qt-red) 10%,transparent)}.qt-viewtoggle{display:inline-flex;border:1px solid var(--qt-border);border-radius:var(--radius);overflow:hidden;flex-shrink:0;height:var(--control-h);align-self:center}.qt-viewtoggle button{display:inline-flex;align-items:center;justify-content:center;width:var(--icon-btn);height:100%;border:none;background:transparent;color:var(--qt-text-muted);padding:0;transition:background .12s ease,color .12s ease}.qt-viewtoggle button:hover{background:var(--qt-surface-hover);color:var(--qt-text)}.qt-viewtoggle button.is-active{background:var(--qt-surface-hover);color:var(--qt-accent)}.qt-shell{display:flex;flex-direction:column;height:100vh;height:100dvh;min-height:0;width:100%;color:var(--qt-text);background:var(--qt-base);padding-bottom:var(--qt-kbd-inset, 0px)}.qt-shell__header{flex:0 0 auto}.qt-shell__main{flex:1;min-height:0;min-width:0;display:flex;flex-direction:column;overflow:hidden}.qt-shell__footer{flex:0 0 auto}.qt-home-layout{display:flex;flex-direction:column;flex:1;min-height:0;padding:var(--space-3);gap:var(--space-3)}.qt-home-layout__toolbar,.qt-home-layout__breadcrumb{flex:0 0 auto}.qt-home-layout__content{flex:1;min-height:0;overflow-y:auto;padding-top:2px}.qt-home-layout__content::-webkit-scrollbar{width:10px}.qt-home-layout__content::-webkit-scrollbar-thumb{background:transparent;border-radius:5px;border:2px solid transparent;background-clip:content-box;transition:background .12s ease}.qt-home-layout__content:hover::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--qt-border) 70%,transparent);background-clip:content-box}.qt-home-layout__content::-webkit-scrollbar-thumb:hover{background:color-mix(in srgb,var(--qt-border) 100%,transparent);background-clip:content-box}.qt-breadcrumb{display:flex;align-items:center;flex-wrap:wrap;gap:4px;padding:var(--space-2) var(--space-3);font-size:var(--fs-caption)}.qt-breadcrumb__crumb{background:transparent;border:none;padding:2px 6px;border-radius:4px;color:var(--qt-text-muted);font-family:inherit;font-size:inherit;cursor:pointer;transition:color .12s ease,background .12s ease}.qt-breadcrumb__crumb:hover{color:var(--qt-text);background:color-mix(in srgb,var(--qt-text) 6%,transparent)}.qt-breadcrumb__crumb.is-current{color:var(--qt-text);cursor:default;font-weight:500}.qt-breadcrumb__sep{color:var(--qt-text-muted);opacity:.5;-webkit-user-select:none;user-select:none}.qt-breadcrumb__group{display:inline-flex;align-items:center;gap:4px}.qt-completion-stamp{position:absolute;top:24px;right:32px;transform:rotate(-6deg);transform-origin:center;z-index:6;color:var(--stamp-color);line-height:0;animation:qt-completion-stamp-in .25s cubic-bezier(.34,1.56,.64,1);pointer-events:none;-webkit-user-select:none;user-select:none}.qt-completion-stamp--pass{--stamp-color: var(--qt-green)}.qt-completion-stamp--fail{--stamp-color: var(--qt-red)}@keyframes qt-completion-stamp-in{0%{opacity:0;transform:rotate(-30deg) scale(1.8)}to{opacity:1;transform:rotate(-6deg) scale(1)}}.qt-tlayout{display:flex;flex-direction:column;flex:1;min-height:0}.qt-tlayout__top,.qt-tlayout__bottom{padding:var(--space-3);display:flex;justify-content:center;flex-shrink:0}.qt-tlayout__top{position:relative;z-index:5;isolation:isolate}.qt-tlayout__middle{flex:1;min-height:0;display:grid;grid-template-columns:minmax(0,1fr) minmax(0,3fr) minmax(0,1fr);gap:var(--space-3);padding:0 3%;position:relative}@media (max-width: 1100px){.qt-tlayout__middle{grid-template-columns:0 minmax(0,1fr) 0;gap:0;padding:0 var(--space-3)}}.qt-tlayout__stage{position:relative;min-height:0;display:flex;flex-direction:column;overflow:hidden}.qt-tlayout__mask{position:absolute;top:0;right:0;bottom:0;left:0;display:none;align-items:center;justify-content:center;background:color-mix(in srgb,var(--qt-base) 25%,transparent);z-index:5;cursor:pointer;pointer-events:none;animation:qt-tlayout-mask-in .16s ease;border:0;padding:0;color:inherit;font:inherit;text-align:inherit}.qt-tlayout__mask:focus-visible{outline:2px solid var(--qt-accent);outline-offset:-4px}.qt-tlayout__middle:has(.qt-typing-arena.is-paused)>.qt-tlayout__stage{filter:blur(2px);transition:filter .12s ease}.qt-tlayout__middle:has(.qt-typing-arena.is-paused)>.qt-tlayout__aside{visibility:hidden}.qt-tlayout__middle:has(.qt-typing-arena.is-paused)>.qt-tlayout__mask{display:flex;pointer-events:auto;cursor:pointer}.qt-tlayout__middle:has(.qt-typing-arena.is-paused)>.qt-tlayout__mask:hover{background:color-mix(in srgb,var(--qt-base) 20%,transparent)}.qt-tlayout__middle:has(.qt-typing-arena.is-paused)>.qt-tlayout__mask:active{background:color-mix(in srgb,var(--qt-base) 15%,transparent)}.qt-tlayout__mask-tip{color:var(--qt-text-muted);font-size:1.5rem;font-weight:500;display:inline-flex;align-items:center;gap:12px}.qt-tlayout__mask-icon{color:var(--qt-accent);flex-shrink:0;animation:qt-tlayout-mask-icon-pulse 1.6s ease-in-out infinite}@keyframes qt-tlayout-mask-icon-pulse{0%,to{transform:translateY(0) scale(1);opacity:1}50%{transform:translateY(-1px) scale(1.06);opacity:.85}}.qt-tlayout__mask-kbd{display:inline-flex;align-items:center;min-width:60px;height:32px;padding:0 12px;font-family:var(--font-mono);font-size:15px;font-weight:600;color:var(--qt-text);background:color-mix(in srgb,var(--qt-base) 60%,transparent);border:1px solid color-mix(in srgb,var(--qt-text) 14%,transparent);border-bottom-width:2px;border-radius:6px;justify-content:center}@keyframes qt-tlayout-mask-in{0%{opacity:0}to{opacity:1}}.qt-tlayout__advance-pill{position:absolute;left:50%;top:100%;transform:translate(-50%,8px);padding:8px 18px;font-family:var(--font-body);font-size:14px;font-weight:500;color:var(--qt-text);background:color-mix(in srgb,var(--qt-base) 96%,transparent);border:1px solid color-mix(in srgb,var(--qt-text) 18%,transparent);border-radius:999px;z-index:4;box-shadow:0 4px 14px color-mix(in srgb,var(--qt-text) 14%,transparent);animation:qt-tlayout-pill-in .22s cubic-bezier(.2,.8,.2,1);white-space:nowrap;pointer-events:none;-webkit-user-select:none;user-select:none}@keyframes qt-tlayout-pill-in{0%{opacity:0;transform:translate(-50%,-4px)}to{opacity:1;transform:translate(-50%,8px)}}.qt-setting-row{padding:var(--space-4) 0}.qt-setting-row.has-divider{border-top:1px solid var(--qt-border)}.qt-setting-row.has-divider:first-child{border-top:none;padding-top:0}.qt-setting-row__title{font-size:var(--fs-body);color:var(--qt-text);font-weight:500;line-height:1.4;letter-spacing:.01em}.qt-setting-row__desc{color:var(--qt-text-muted);font-size:var(--fs-caption);margin-top:6px;line-height:1.6}.qt-setting-row__control{margin-top:12px;display:flex;align-items:center;gap:var(--space-2);flex-wrap:wrap}.qt-setting-btn{padding:6px 14px;background:var(--qt-mantle);border:1px solid color-mix(in srgb,var(--qt-text) 12%,transparent);border-radius:6px;color:var(--qt-text);font-size:13px;cursor:pointer}.qt-setting-btn:hover{background:color-mix(in srgb,var(--qt-text) 8%,var(--qt-mantle))}.qt-setting-range{flex:1;min-width:100px;max-width:180px;accent-color:var(--qt-accent)}.qt-setting-range:disabled{opacity:.4}.qt-setting-range-value{min-width:32px;text-align:right;font-family:var(--font-mono);font-size:12px;color:var(--qt-text-muted)}.qt-setting-row.is-revealed{animation:qt-setting-row-pulse 1.6s ease-out;border-radius:6px}@keyframes qt-setting-row-pulse{0%{background:color-mix(in srgb,var(--qt-accent) 22%,transparent)}to{background:transparent}}.qt-segmented{display:inline-flex;border:1px solid var(--qt-border);border-radius:var(--radius);overflow:hidden;background:var(--qt-base)}.qt-segmented__btn{background:transparent;border:none;color:var(--qt-text-muted);padding:0 var(--space-3);height:28px;font-family:inherit;font-size:var(--fs-ui);cursor:pointer;transition:background .12s ease,color .12s ease}.qt-segmented__btn:hover{color:var(--qt-text);background:var(--qt-surface-hover)}.qt-segmented__btn.is-active{background:var(--qt-accent);color:#fff}.qt-switch{display:inline-flex;align-items:center;gap:8px;background:transparent;border:none;padding:0;cursor:pointer;color:var(--qt-text-muted);font-family:inherit;font-size:var(--fs-ui)}.qt-switch__track{position:relative;width:34px;height:20px;border-radius:10px;background:var(--qt-border);transition:background .16s ease}.qt-switch__thumb{position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:50%;background:#fff;transition:transform .16s ease}.qt-switch.is-on .qt-switch__track{background:var(--qt-accent)}.qt-switch.is-on .qt-switch__thumb{transform:translate(14px)}.qt-switch.is-on{color:var(--qt-text)}.qt-panel-header{padding-bottom:var(--space-4);border-bottom:1px solid var(--qt-border);margin-bottom:var(--space-5)}.qt-panel-header__title{font-size:1.35rem;font-weight:600;color:var(--qt-text);margin:0;letter-spacing:.02em}.qt-panel-header__sub{margin:6px 0 0;color:var(--qt-text-muted);font-size:var(--fs-caption);line-height:1.5}.qt-toast-stack{position:fixed;left:50%;bottom:32px;transform:translate(-50%);z-index:300;display:flex;flex-direction:column;align-items:center;gap:8px;pointer-events:none}.qt-toast{padding:8px 16px;min-width:120px;max-width:min(90vw,460px);border-radius:8px;font-size:13px;font-family:inherit;color:var(--qt-text);background:var(--qt-mantle);border:1px solid color-mix(in srgb,var(--qt-text) 14%,transparent);box-shadow:0 8px 24px #00000059;text-align:center;pointer-events:auto;opacity:0;transform:translateY(6px);transition:opacity .16s ease,transform .16s ease}.qt-toast.is-in{opacity:1;transform:translateY(0)}.qt-toast.is-out{opacity:0;transform:translateY(-4px)}.qt-toast--success{border-color:color-mix(in srgb,var(--qt-accent) 40%,transparent);color:var(--qt-accent)}.qt-toast--warn{border-color:color-mix(in srgb,var(--qt-yellow, #f9e2af) 60%,transparent);color:var(--qt-yellow, #f9e2af)}.qt-toast--error{border-color:color-mix(in srgb,var(--qt-red, #f38ba8) 60%,transparent);color:var(--qt-red, #f38ba8)}.qt-caret{position:absolute;left:0;top:0;width:2px;height:1.4em;background:var(--qt-accent);border-radius:1px;pointer-events:none;z-index:3;animation:qt-caret-blink .9s steps(2,start) infinite;will-change:transform,height}.qt-caret.is-paused{animation:none;opacity:0}.qt-caret.is-hidden{display:none!important}.qt-caret--shadow{background:var(--qt-text-muted);opacity:.4;animation:none}@keyframes qt-caret-blink{to{opacity:0}}.qt-char{position:relative;transition:color 80ms ease,background 80ms ease}.qt-char.is-hit{color:var(--qt-green)}.qt-char.is-miss{color:var(--qt-red)}.qt-char__placeholder{color:var(--qt-text-muted);opacity:.55}.qt-char-icon{display:inline-block;width:.9em;height:.9em;vertical-align:-.1em;color:inherit;opacity:.55}.qt-char.is-hit .qt-char-icon{opacity:.7}.qt-char.is-miss .qt-char-icon{opacity:1}.qt-char-icon--enter{margin-right:2px}.qt-char.is-newline{position:relative;display:inline}.qt-char.is-newline .qt-char-icon--enter{position:absolute;left:0;top:50%;transform:translateY(-50%);margin-right:0;pointer-events:none}.qt-char.is-newline:after{content:"\a";white-space:pre}.qt-char-dot{opacity:.55}.qt-char.is-hit .qt-char-dot{opacity:.7}.qt-char.is-miss .qt-char-dot{opacity:1}.qt-typing-arena{position:relative;padding:0;cursor:text;display:flex;flex-direction:column;flex:1;min-height:0}.qt-typing-arena.is-shaking{animation:qt-arena-shake .3s cubic-bezier(.36,.07,.19,.97)}@keyframes qt-arena-shake{10%,90%{transform:translate(-2px)}20%,80%{transform:translate(4px)}30%,50%,70%{transform:translate(-6px)}40%,60%{transform:translate(6px)}}.qt-typing-arena__text{font-family:var(--font-mono);font-size:var(--qt-typing-font-size, 1.05rem);letter-spacing:var(--qt-typing-letter-spacing, 0);line-height:1.85;white-space:pre-wrap;word-break:var(--qt-typing-word-break, break-word);min-height:0;padding:24px 32px;overflow-y:auto;flex:1;color:var(--qt-text);position:relative;z-index:1;transition:filter .16s ease}.qt-typing-arena__text.is-blind .qt-char:not(.is-hit):not(.is-miss):not(.is-recover):not(.is-cursor){color:transparent}.qt-typing-arena__text.is-blind .qt-char.is-cursor:not(.is-hit):not(.is-miss){color:var(--qt-text-muted)}.qt-typing-arena__text.is-ghost .qt-char:not(.is-hit):not(.is-miss){color:var(--qt-text-muted);opacity:.35}.qt-shadow-marker{display:inline-block;width:0;height:1em;vertical-align:baseline}.qt-char.is-eof{display:inline-block;width:0}.qt-typing-arena__editor{position:absolute;width:1px;z-index:2;padding:0;border:0;margin:0;outline:none;background:transparent;color:transparent;caret-color:transparent;font-family:var(--font-mono);font-size:1.05rem;line-height:1.85;white-space:pre;opacity:0}.qt-typing-arena__preedit{position:absolute;z-index:3;padding:3px 8px;font-family:var(--font-mono);font-size:.85rem;line-height:1.2;color:var(--qt-accent);background:var(--qt-mantle);border:1px solid color-mix(in srgb,var(--qt-accent) 40%,transparent);border-radius:999px;box-shadow:0 4px 12px color-mix(in srgb,var(--qt-accent) 30%,transparent);pointer-events:none;white-space:pre;transform:translateY(calc(-100% - 4px))}.qt-typing-arena__preedit-ch{color:inherit}.qt-typing-arena__preedit-ch.is-wrong{color:var(--qt-red, #e5484d)}.qt-typing-arena.is-paused{-webkit-user-select:none;user-select:none}.qt-typing-arena.is-cursor-idle,.qt-typing-arena.is-cursor-idle *{cursor:none}.qt-hud-more{background:var(--qt-mantle);border-radius:10px;box-shadow:0 10px 30px #00000047,0 0 0 1px color-mix(in srgb,var(--qt-text) 6%,transparent);padding:4px;outline:none;z-index:60;display:flex;flex-direction:column;gap:1px}.qt-hud-more__item{display:flex;align-items:center;gap:10px;width:100%;padding:8px 10px;background:transparent;border:none;border-radius:6px;cursor:pointer;color:var(--qt-text);font-size:var(--fs-ui);font-family:inherit;text-align:left;transition:background .12s ease,color .12s ease}.qt-hud-more__item:hover:not(:disabled){background:var(--qt-surface-hover)}.qt-hud-more__item:disabled{opacity:.4;cursor:not-allowed}.qt-hud-more__item:focus-visible{outline:none;box-shadow:0 0 0 2px color-mix(in srgb,var(--qt-accent) 55%,transparent)}.qt-hud-more__item.is-on .qt-hud-more__icon{color:var(--qt-accent)}.qt-hud-more__icon{display:inline-flex;align-items:center;justify-content:center;color:var(--qt-text-muted)}.qt-hud-more__label{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.qt-hud-more__kbd{color:var(--qt-text-muted);font-size:var(--fs-caption);font-family:var(--font-mono);letter-spacing:.03em;white-space:nowrap;padding:1px 6px;border-radius:4px;background:color-mix(in srgb,var(--qt-text) 6%,transparent)}.qt-hud-more__check{margin-left:auto;display:inline-flex;align-items:center;justify-content:center;width:16px;color:var(--qt-accent);flex-shrink:0}.qt-hud{display:flex;flex-direction:column;align-items:center;width:100%;color:var(--qt-text-muted);font-family:var(--font-mono);font-size:var(--fs-caption);-webkit-user-select:none;user-select:none;pointer-events:none}.qt-hud>*{pointer-events:auto}.qt-hud__bar{display:flex;align-items:center;justify-content:center;gap:6px;flex-wrap:wrap;max-width:100%}.qt-hud-btn--pause.is-running{color:var(--qt-green)}.qt-hud-btn--pause.is-paused{color:var(--qt-accent);animation:qt-hud-pulse 1.4s ease-in-out infinite}@keyframes qt-hud-pulse{0%,to{opacity:1}50%{opacity:.55}}.qt-hud-item{color:var(--qt-text-muted);display:inline-flex;align-items:center;gap:4px;padding:0 6px;height:24px;box-sizing:border-box}.qt-hud-item b{color:var(--qt-text);font-weight:600}.qt-hud-item--warn,.qt-hud-item--warn b{color:var(--qt-danger, #e5484d)}.qt-hud-unit{color:var(--qt-text-muted);font-size:10px;margin-left:3px;letter-spacing:.03em}.qt-hud-icon{color:var(--qt-text-muted);flex-shrink:0}.qt-hud-sep{display:none}.qt-hud-btn{display:inline-flex;align-items:center;justify-content:center;width:24px;height:24px;padding:0;background:transparent;border:none;color:var(--qt-text-muted);border-radius:4px;cursor:pointer;outline:none;transition:color .12s ease,background .12s ease}.qt-hud-btn:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb,var(--qt-accent) 60%,transparent)}.qt-hud-btn:hover:not(:disabled){color:var(--qt-accent);background:color-mix(in srgb,var(--qt-text) 8%,transparent)}.qt-hud-btn.is-on{color:var(--qt-accent)}.qt-hud-btn.is-off{opacity:.5}.qt-hud-btn:disabled{opacity:.3;cursor:not-allowed}.qt-tk{--qt-tk-user-scale: 1.3;--qt-tk-native-w: 454px;--qt-tk-native-h: 170px;--qt-tk-fit-scale: calc((100vw - 32px) / var(--qt-tk-native-w));--qt-tk-scale: min(var(--qt-tk-user-scale), var(--qt-tk-fit-scale));width:calc(var(--qt-tk-native-w) * var(--qt-tk-scale));height:calc(var(--qt-tk-native-h) * var(--qt-tk-scale));display:flex;justify-content:center;-webkit-user-select:none;user-select:none;pointer-events:none;font-family:var(--font-mono)}.qt-tk__stage{position:relative;width:var(--qt-tk-native-w);display:flex;flex-direction:column;padding:10px;box-sizing:border-box;transform:scale(var(--qt-tk-scale));transform-origin:top center}.qt-tk__row{display:flex;justify-content:space-between}.qt-tk__row.is-space-row{justify-content:flex-start}.qt-tk__key{position:relative;width:28px;height:28px;margin:1px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:1px;box-sizing:border-box;border:1px solid color-mix(in srgb,var(--qt-text) 6%,transparent);border-radius:5px 5px 7px 7px;background:color-mix(in srgb,var(--qt-mantle) 55%,transparent);backdrop-filter:blur(12px) saturate(1.4);-webkit-backdrop-filter:blur(12px) saturate(1.4);box-shadow:0 1px color-mix(in srgb,var(--qt-text) 10%,transparent) inset,0 2px 6px #0000002e,0 1px 2px #0000001a;color:var(--qt-text);opacity:.85;font-size:13px;font-weight:500;transition:background .2s ease,color .2s ease,border-color .2s ease,opacity .2s ease,transform .12s ease}.qt-tk__key.is-tab{width:42px;font-size:10px}.qt-tk__key.is-caps,.qt-tk__key.is-enter{width:49px;font-size:10px}.qt-tk__key.is-lshift,.qt-tk__key.is-rshift{width:63px;font-size:10px}.qt-tk__key.is-backspace{width:42px;font-size:10px}.qt-tk__key.is-space{width:140px;font-size:10px}.qt-tk__key.is-bump:after{content:"";position:absolute;bottom:3px;left:50%;transform:translate(-50%);width:8px;height:2px;background:currentColor;opacity:.6;border-radius:1px}.qt-tk__key-sub{font-size:9px;opacity:.7;line-height:1}.qt-tk__key-main{line-height:1}.qt-tk__key.is-next{background:transparent;color:var(--qt-accent);border-color:var(--qt-accent);border-width:2px;opacity:1}.qt-tk__key.is-shift-hint{background:transparent;color:var(--qt-accent);border-color:var(--qt-accent);opacity:.9}.qt-tk__key.is-wrong{background:transparent;color:var(--qt-red, #e5484d);border-color:var(--qt-red, #e5484d);border-width:2px;opacity:1}.qt-tk__hand{color:var(--qt-text);opacity:.75;pointer-events:none;z-index:2}.qt-tk__hand svg{width:100%;height:100%;display:block}.qt-tk__hand.is-interactive{pointer-events:auto;cursor:grab;touch-action:none}.qt-tk__hand.is-interactive:active{cursor:grabbing}.qt-tk__hand.is-interactive svg{pointer-events:none}.qt-tk__row{position:relative;z-index:1}@media (max-width: 640px){.qt-tk{display:none}}.qt-cardnav{display:inline-flex;align-items:center;gap:8px;max-width:500px;color:inherit;-webkit-user-select:none;user-select:none;line-height:1}.qt-cardnav__btn{display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;padding:0;border:none;border-radius:3px;background:transparent;color:inherit;cursor:pointer;transition:background .12s ease,color .12s ease}.qt-cardnav__btn:hover:not(:disabled){background:color-mix(in srgb,var(--qt-text) 12%,transparent);color:var(--qt-text)}.qt-cardnav__btn:disabled{opacity:.3;cursor:not-allowed}.qt-cardnav__dots{display:inline-flex;align-items:center;gap:4px}.qt-cardnav__dot{width:7px;height:7px;padding:0;border:1px solid currentColor;border-radius:50%;background:transparent;opacity:.4;cursor:pointer;transition:opacity .12s ease,background .12s ease,transform .12s ease,box-shadow .12s ease}.qt-cardnav__dot:hover{opacity:.75}.qt-cardnav__dot.is-done{background:currentColor;border-color:transparent;opacity:.85}.qt-cardnav__dot.is-current{opacity:1;box-shadow:0 0 0 1.5px var(--qt-accent, var(--qt-green));transform:scale(1.2)}.qt-cardnav__dot.is-current.is-done{background:var(--qt-accent, var(--qt-green))}.qt-cardnav__track{position:relative;flex:1 1 auto;min-width:100px;height:3px;border-radius:2px;background:currentColor;opacity:.22}.qt-cardnav__track-fill{position:absolute;left:0;top:0;bottom:0;border-radius:2px;background:currentColor;opacity:.75}.qt-cardnav__track-cursor{position:absolute;top:50%;width:6px;height:6px;margin-left:-3px;margin-top:-3px;border-radius:50%;background:var(--qt-accent, var(--qt-green))}.qt-cardnav__frac{font-family:var(--font-mono, ui-monospace, monospace);font-size:var(--fs-caption);min-width:3.5em;text-align:center;color:inherit;opacity:.8;display:inline-flex;align-items:center;justify-content:center;gap:2px}.qt-cardnav__sep{opacity:.4;margin:0 1px}.qt-cardnav__jump-btn{padding:0 2px;border:none;background:transparent;color:inherit;font:inherit;cursor:pointer;border-radius:3px}.qt-cardnav__jump-btn:hover{background:color-mix(in srgb,var(--qt-text) 12%,transparent);color:var(--qt-text)}.qt-cardnav__jump{width:2.4em;padding:0 2px;border:1px solid var(--qt-mauve, currentColor);border-radius:3px;background:transparent;color:var(--qt-text);font:inherit;text-align:center;outline:none}.qt-cardnav__frac--editing{opacity:1}.qt-carousel{position:relative;width:100%;flex:1;min-height:0;display:flex;justify-content:center;align-items:stretch;overflow:hidden}.qt-carousel__current{position:relative;z-index:5;width:100%;max-width:800px;display:flex;flex-direction:column;min-height:0}.qt-tooltip{background:var(--qt-mantle);color:var(--qt-text);border:1px solid var(--qt-border);border-radius:6px;padding:6px 10px;font-size:var(--fs-caption);font-family:var(--font-body);box-shadow:0 4px 16px #0003;z-index:100;animation:qt-tooltip-in .1s ease-out}.qt-tooltip__arrow{fill:var(--qt-mantle)}@keyframes qt-tooltip-in{0%{opacity:0;transform:scale(.96)}to{opacity:1;transform:scale(1)}}.qt-question{min-width:0;overflow:hidden}.qt-question__title{color:var(--qt-text);font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.qt-question__subtitle{margin-top:4px;color:var(--qt-text-muted);font-size:.85em;line-height:1.4;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}.qt-neighbor{display:grid;grid-template-columns:auto minmax(0,1fr);align-items:start;gap:10px;box-sizing:border-box;width:100%;max-height:60vh;overflow:hidden;padding:0;background:transparent;border:0;cursor:pointer;font-family:var(--font-mono);font-size:.9rem;color:var(--qt-text-muted);text-align:left;opacity:.55;transition:opacity .14s ease,transform .14s ease}.qt-neighbor:hover{opacity:1}.qt-neighbor:active{transform:scale(.98)}.qt-neighbor--next{grid-template-columns:minmax(0,1fr) auto;text-align:right}.qt-neighbor__arrow{flex-shrink:0;color:var(--qt-text-muted);transition:color .14s ease}.qt-neighbor:hover .qt-neighbor__arrow{color:var(--qt-accent)}.qt-cardbase{flex:1;min-height:0;display:flex;flex-direction:column;padding:var(--space-3);gap:var(--space-2)}.qt-cardbase__prompt{color:var(--qt-text-muted);font-size:.95rem;line-height:1.5}.qt-cardbase__arena{flex:1;min-height:0;min-width:0;display:flex;flex-direction:column}.qt-speak{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;background:transparent;border:none;color:var(--qt-text-muted);cursor:pointer;transition:color .12s ease}.qt-speak:hover{color:var(--qt-accent)}.qt-card{position:relative;width:100%;height:100%;padding:var(--space-3);overflow-y:auto;min-height:0;display:flex}.qt-card--centered{align-items:safe center;justify-content:safe center}.qt-card--flow{flex-direction:column}.qt-card__stack{display:flex;flex-direction:column;gap:var(--space-3);width:100%;max-width:900px;margin:0 auto}.qt-card--flow .qt-card__stack{flex:1;min-height:0}.qt-card--centered .qt-card__stack{align-items:center}.qt-card__slot{width:100%}.qt-card__title{font-size:1.3rem;font-weight:600;color:var(--qt-text);text-align:center;flex-shrink:0;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;word-break:break-word}.qt-card__phonetic{font-family:var(--font-mono);font-size:1rem;color:var(--qt-text-muted);text-align:center;letter-spacing:.02em}.qt-card__question{color:var(--qt-text-muted);font-size:.95rem;line-height:1.6;max-height:30vh;overflow-y:auto;flex-shrink:0}.qt-card__question img{max-width:min(100%,480px);height:auto;display:block;margin:var(--space-3) auto}.qt-card__arena{min-height:0;min-width:0;display:flex;flex-direction:column}.qt-card--flow .qt-card__arena{flex:1}.qt-card__arena .qt-typing-arena__text{padding:0}.qt-card__gloss{font-size:1rem;color:var(--qt-text);text-align:center;line-height:1.5}.qt-card__image{margin:0 auto;text-align:center}.qt-card__image img{max-width:100%;height:auto;display:inline-block;margin:0 auto}.qt-card__image .qt-md,.qt-card__image .qt-md p{margin:0}.qt-card--word .qt-card__stack{max-width:720px}.qt-card--word .qt-card__arena .qt-typing-arena__text{font-size:3rem;font-weight:500;letter-spacing:.05em;text-align:center}.qt-card--word .qt-card__image{width:120px;opacity:.85}.qt-card--sentence .qt-card__image{width:140px;opacity:.85}.qt-card--article .qt-card__image{width:260px;opacity:.9}.qt-card--snippet .qt-card__image{width:200px;opacity:.9}.qt-card--sentence .qt-card__arena .qt-typing-arena__text{font-size:1.6rem;line-height:1.6;text-align:center}.qt-card--snippet .qt-card__stack{max-width:720px}.qt-card--snippet .qt-card__title{font-size:1.15rem;font-weight:500;color:var(--qt-text-muted);letter-spacing:.05em}.qt-card--snippet .qt-card__arena .qt-typing-arena__text{font-size:1.4rem;line-height:2;text-align:center;letter-spacing:.03em}.qt-card--article .qt-card__arena .qt-typing-arena__text{font-size:1.15rem;line-height:1.7}.qt-card--qa .qt-card__arena .qt-typing-arena__text{font-size:1.1rem;line-height:1.7}.qt-card--code .qt-card__stack{font-family:var(--font-mono)}.qt-card--code .qt-card__title{font-size:1.15rem}.qt-card--code .qt-card__question pre,.qt-card--code .qt-card__question code{font-family:var(--font-mono);font-size:.85rem}.qt-card--code .qt-card__question{font-size:.9rem;line-height:1.5}.qt-card--code .qt-card__arena .qt-typing-arena__text{font-family:var(--font-mono);white-space:pre-wrap;text-align:left}.qt-word__arena-wrap{position:relative;width:fit-content;margin:0 auto}.qt-word__speak{position:absolute;left:100%;top:50%;transform:translateY(-50%);margin-left:8px;display:flex;align-items:center;justify-content:center}.qt-sentence__arena-wrap{position:relative;width:fit-content;max-width:100%;margin:0 auto}.qt-sentence__speak{position:absolute;left:100%;top:50%;transform:translateY(-50%);margin-left:8px;display:flex;align-items:center}.qt-confirm__overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:#0000008c;z-index:200;animation:qt-confirm-fade .12s ease}.qt-confirm__content{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:201;width:min(420px,calc(100vw - 32px));background:var(--qt-base);border:1px solid color-mix(in srgb,var(--qt-text) 12%,transparent);border-radius:12px;box-shadow:0 24px 60px #00000073;padding:20px 22px 16px;animation:qt-confirm-pop .14s ease}@keyframes qt-confirm-fade{0%{opacity:0}to{opacity:1}}@keyframes qt-confirm-pop{0%{opacity:0;transform:translate(-50%,-48%)}to{opacity:1;transform:translate(-50%,-50%)}}.qt-confirm__title{font-size:15px;font-weight:600;color:var(--qt-text);margin:0 0 10px}.qt-confirm__message{color:var(--qt-text);font-size:13.5px;line-height:1.55;margin:0 0 18px;word-break:break-word}.qt-confirm__actions{display:flex;justify-content:flex-end;gap:8px}.qt-confirm__btn{padding:6px 16px;background:var(--qt-mantle);border:1px solid color-mix(in srgb,var(--qt-text) 12%,transparent);border-radius:6px;color:var(--qt-text);font-size:13px;cursor:pointer;font-family:inherit;min-width:64px}.qt-confirm__btn:hover{background:color-mix(in srgb,var(--qt-text) 8%,var(--qt-mantle))}.qt-confirm__btn:focus-visible{outline:2px solid var(--qt-accent);outline-offset:1px}.qt-confirm__btn--primary{background:var(--qt-accent);color:var(--qt-base);border-color:var(--qt-accent)}.qt-confirm__btn--primary:hover{filter:brightness(1.05)}.qt-confirm__btn--danger{background:var(--qt-red, #f38ba8);border-color:var(--qt-red, #f38ba8);color:var(--qt-base)}.qt-confirm__btn--danger:hover{filter:brightness(1.05)}.qt-danger-btn{background:transparent;border:1px solid var(--qt-border);color:var(--qt-text-muted);padding:0 var(--space-3);height:28px;border-radius:var(--radius);font-family:inherit;font-size:var(--fs-ui);cursor:pointer;transition:color .12s ease,border-color .12s ease,background .12s ease}.qt-danger-btn:hover:not(:disabled){color:var(--qt-red);border-color:color-mix(in srgb,var(--qt-red) 50%,var(--qt-border));background:color-mix(in srgb,var(--qt-red) 10%,transparent)}.qt-danger-btn:disabled{opacity:.4;cursor:not-allowed}.qt-kcal__overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:#0000008c;z-index:100;animation:qt-kcal-fade .12s ease}.qt-kcal__content{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:101;display:flex;flex-direction:column;width:min(880px,calc(100vw - 32px));max-height:calc(100dvh - 32px);background:var(--qt-base);border:1px solid color-mix(in srgb,var(--qt-text) 12%,transparent);border-radius:12px;box-shadow:0 24px 60px #00000073;overflow:hidden;animation:qt-kcal-pop .14s ease}@keyframes qt-kcal-fade{0%{opacity:0}to{opacity:1}}@keyframes qt-kcal-pop{0%{opacity:0;transform:translate(-50%,-48%)}to{opacity:1;transform:translate(-50%,-50%)}}.qt-kcal__header{display:flex;align-items:center;gap:16px;padding:12px 16px;border-bottom:1px solid color-mix(in srgb,var(--qt-text) 10%,transparent)}.qt-kcal__title{font-size:15px;font-weight:600;color:var(--qt-text);margin:0}.qt-kcal__hint{flex:1;color:var(--qt-text-muted);font-size:12px}.qt-kcal__close{background:transparent;border:0;color:var(--qt-text-muted);font-size:20px;line-height:1;cursor:pointer;padding:4px 8px}.qt-kcal__close:hover{color:var(--qt-text)}.qt-kcal__body{display:flex;flex-direction:column;gap:16px;padding:20px 24px;min-height:0;overflow:auto}.qt-kcal__nav{display:flex;align-items:center;gap:12px}.qt-kcal__pose-label{flex:1;display:flex;align-items:baseline;justify-content:center;gap:12px}.qt-kcal__pose-side{color:var(--qt-text-muted);font-size:13px}.qt-kcal__pose-name{color:var(--qt-accent);font-size:22px;font-weight:600;font-family:var(--font-mono)}.qt-kcal__pose-idx{color:var(--qt-text-muted);font-size:12px;font-family:var(--font-mono)}.qt-kcal__stage{display:flex;justify-content:center;padding:8px;background:color-mix(in srgb,var(--qt-text) 3%,transparent);border-radius:8px;overflow:hidden;position:relative;z-index:0}.qt-kcal__nav,.qt-kcal__actions,.qt-kcal__coords{position:relative;z-index:1}.qt-kcal__coords{display:flex;align-items:center;gap:16px;padding:8px 12px;background:color-mix(in srgb,var(--qt-text) 5%,transparent);border-radius:6px;font-family:var(--font-mono);font-size:12.5px;color:var(--qt-text)}.qt-kcal__svg-tag{color:var(--qt-accent);font-size:11.5px}.qt-kcal__dirty{margin-left:auto;padding:2px 8px;background:color-mix(in srgb,var(--qt-red, #f38ba8) 22%,transparent);color:var(--qt-red, #f38ba8);border-radius:999px;font-size:11px}.qt-kcal__customized{margin-left:auto;color:var(--qt-accent);font-size:11px}.qt-kcal__actions{display:flex;gap:8px;justify-content:flex-end}.qt-kcal__footer{display:flex;align-items:center;gap:8px;padding:12px 16px;border-top:1px solid color-mix(in srgb,var(--qt-text) 10%,transparent);background:color-mix(in srgb,var(--qt-text) 3%,transparent)}.qt-kcal__footer-spacer{flex:1}.qt-kcal__btn{padding:6px 14px;background:var(--qt-mantle);border:1px solid color-mix(in srgb,var(--qt-text) 12%,transparent);border-radius:6px;color:var(--qt-text);font-size:13px;cursor:pointer;font-family:inherit}.qt-kcal__btn:hover:not(:disabled){background:color-mix(in srgb,var(--qt-text) 8%,var(--qt-mantle))}.qt-kcal__btn:disabled{opacity:.4;cursor:not-allowed}.qt-kcal__btn--primary{background:var(--qt-accent);color:var(--qt-base);border-color:var(--qt-accent)}.qt-kcal__btn--primary:hover:not(:disabled){filter:brightness(1.05)}.qt-kcal__picker-overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:#000000a6;z-index:110;animation:qt-kcal-fade .12s ease}.qt-kcal__picker{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:111;display:flex;flex-direction:column;width:min(720px,calc(100vw - 32px));max-height:calc(100dvh - 48px);background:var(--qt-base);border:1px solid color-mix(in srgb,var(--qt-text) 12%,transparent);border-radius:12px;box-shadow:0 24px 60px #0000008c;overflow:hidden}.qt-kcal__picker-header{display:flex;align-items:center;padding:12px 16px;border-bottom:1px solid color-mix(in srgb,var(--qt-text) 10%,transparent)}.qt-kcal__picker-title{flex:1;font-size:14px;font-weight:600;color:var(--qt-text);margin:0}.qt-kcal__picker-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(96px,1fr));gap:8px;padding:16px;overflow-y:auto}.qt-kcal__picker-cell{display:flex;align-items:center;justify-content:center;height:96px;background:color-mix(in srgb,var(--qt-text) 4%,transparent);border:1px solid color-mix(in srgb,var(--qt-text) 10%,transparent);border-radius:8px;cursor:pointer;color:var(--qt-text);padding:4px}.qt-kcal__picker-cell:hover{background:color-mix(in srgb,var(--qt-accent) 10%,transparent);border-color:color-mix(in srgb,var(--qt-accent) 40%,transparent)}.qt-kcal__picker-cell.is-selected{border-color:var(--qt-accent);background:color-mix(in srgb,var(--qt-accent) 15%,transparent)}.qt-shortcuts{display:flex;flex-direction:column;gap:20px;margin-top:12px}.qt-shortcuts__group-title{font-size:12px;font-weight:600;color:var(--qt-text-muted);text-transform:uppercase;letter-spacing:.05em;margin-bottom:6px}.qt-shortcut-row{display:grid;grid-template-columns:1fr auto auto auto;grid-column-gap:8px;align-items:center;padding:6px 0;border-top:1px solid color-mix(in srgb,var(--qt-text) 6%,transparent)}.qt-shortcut-row:first-of-type{border-top:0}.qt-shortcut-row__label{font-size:13px;color:var(--qt-text)}.qt-shortcut-row__key{min-width:120px;padding:4px 10px;background:color-mix(in srgb,var(--qt-text) 4%,transparent);border:1px solid color-mix(in srgb,var(--qt-text) 12%,transparent);border-radius:6px;color:var(--qt-text);cursor:pointer;font-family:var(--font-mono);font-size:12px;text-align:center}.qt-shortcut-row__key:hover{background:color-mix(in srgb,var(--qt-text) 8%,transparent)}.qt-shortcut-row__key.is-recording{border-color:var(--qt-accent);background:color-mix(in srgb,var(--qt-accent) 12%,transparent)}.qt-shortcut-row__kbd{font-family:var(--font-mono);font-size:12px}.qt-shortcut-row__disabled{color:var(--qt-text-muted);font-style:italic}.qt-shortcut-row__hint{color:var(--qt-accent)}.qt-shortcut-row__btn{width:24px;height:24px;padding:0;background:transparent;border:0;border-radius:4px;color:var(--qt-text-muted);font-size:14px;cursor:pointer;line-height:1}.qt-shortcut-row__btn:hover{background:color-mix(in srgb,var(--qt-text) 8%,transparent);color:var(--qt-text)}.qt-shortcut-row__btn--danger:hover{color:var(--qt-red, #f38ba8)}.qt-shortcut-row__warn{grid-column:1 / -1;padding:4px 0 2px;font-size:11.5px;color:color-mix(in srgb,var(--qt-red, #f38ba8) 80%,var(--qt-text));display:flex;gap:12px;flex-wrap:wrap}.qt-settings-search{display:flex;flex-direction:column;gap:var(--space-3)}.qt-settings-search__count{font-size:var(--fs-caption);color:var(--qt-text-muted);letter-spacing:.03em;padding-bottom:var(--space-2)}.qt-settings-search__group{display:flex;flex-direction:column;gap:2px}.qt-settings-search__group-label{font-size:var(--fs-caption);color:var(--qt-text-muted);text-transform:uppercase;letter-spacing:.08em;padding:6px 8px}.qt-settings-search__row{display:flex;flex-direction:column;gap:4px;padding:10px 12px;background:transparent;border:none;border-radius:8px;color:var(--qt-text);font-family:inherit;text-align:left;cursor:pointer;transition:background .12s ease}.qt-settings-search__row:hover{background:var(--qt-surface-hover)}.qt-settings-search__row-title{font-size:var(--fs-ui);font-weight:500}.qt-settings-search__row-desc{font-size:var(--fs-caption);color:var(--qt-text-muted);line-height:1.5}.qt-settings-search__empty{padding:var(--space-5);text-align:center;color:var(--qt-text-muted);font-size:var(--fs-ui)}.qt-settings__highlight{background:color-mix(in srgb,var(--qt-accent) 28%,transparent);color:inherit;padding:0 2px;border-radius:2px}.qt-settings-sidebar{display:flex;flex-direction:column;gap:var(--space-1);padding:var(--space-2) var(--space-1);height:100%;overflow-y:auto}.qt-settings-sidebar__group{display:flex;flex-direction:column;gap:2px}.qt-settings-sidebar__group-row{display:flex;align-items:center;gap:6px;padding:6px 8px;background:transparent;border:none;border-radius:4px;color:var(--qt-text-muted);font-size:var(--fs-caption);letter-spacing:.05em;text-transform:uppercase;cursor:pointer;transition:color .12s ease,background .12s ease}.qt-settings-sidebar__group-row:hover{color:var(--qt-text)}.qt-settings-sidebar__chevron{flex-shrink:0;transition:transform .16s ease}.qt-settings-sidebar__chevron.is-open{transform:rotate(90deg)}.qt-settings-sidebar__group-label{flex:1;min-width:0;text-align:left;overflow:hidden;text-overflow:ellipsis}.qt-settings-sidebar__tabs{display:flex;flex-direction:column;gap:1px;padding-left:12px}.qt-settings-sidebar__tab{display:block;width:100%;padding:6px 10px;background:transparent;border:none;border-radius:4px;color:var(--qt-text);font-size:var(--fs-ui);text-align:left;cursor:pointer;transition:color .12s ease,background .12s ease;outline:none}.qt-settings-sidebar__tab:hover{background:var(--qt-surface-hover)}.qt-settings-sidebar__tab.is-active{background:color-mix(in srgb,var(--qt-accent) 12%,transparent);color:var(--qt-accent);font-weight:500}.qt-settings-sidebar__tab:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb,var(--qt-accent) 60%,transparent)}.qt-settings-sidebar__tab.is-dim,.qt-settings-sidebar__group-row.is-dim{opacity:.4;cursor:not-allowed}.qt-settings-sidebar__tab.is-dim:hover{background:transparent}.qt-settings-sidebar__tab-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis}.qt-settings-sidebar__tab{display:flex;align-items:center;gap:8px}.qt-settings-sidebar__count{flex-shrink:0;padding:0 6px;min-width:20px;height:18px;display:inline-flex;align-items:center;justify-content:center;background:color-mix(in srgb,var(--qt-accent) 20%,transparent);color:var(--qt-accent);border-radius:9px;font-size:11px;font-weight:600;font-family:var(--font-mono)}.qt-settings__overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:#0006;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);animation:qt-fade-in .12s ease-out;z-index:40}@keyframes qt-fade-in{0%{opacity:0}to{opacity:1}}.qt-settings__content{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);width:min(900px,92vw);height:min(620px,85dvh);background:var(--qt-mantle);border-radius:16px;box-shadow:0 12px 40px #0006;display:flex;flex-direction:column;overflow:hidden;z-index:50;animation:qt-dialog-in .16s ease-out}.qt-settings__content.is-expanded{width:96vw;height:92dvh}@keyframes qt-dialog-in{0%{opacity:0;transform:translate(-50%,-50%) scale(.96)}to{opacity:1;transform:translate(-50%,-50%) scale(1)}}.qt-settings__titlebar{height:40px;padding:0 var(--space-3);display:flex;align-items:center;justify-content:space-between;flex-shrink:0}.qt-settings__brand{display:flex;align-items:center;gap:8px;color:var(--qt-text-muted)}.qt-settings__brand-text{margin:0;font-size:var(--fs-caption);color:var(--qt-text);letter-spacing:.08em;-webkit-user-select:none;user-select:none}.qt-settings__titlebar-actions{display:flex;align-items:center;gap:2px}.qt-settings__icon-btn{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;padding:0;background:transparent;border:none;border-radius:4px;color:var(--qt-text-muted);cursor:pointer;outline:none;transition:color .12s ease,background .12s ease}.qt-settings__icon-btn:hover{color:var(--qt-text);background:var(--qt-surface-hover)}.qt-settings__icon-btn:focus-visible{box-shadow:0 0 0 2px color-mix(in srgb,var(--qt-accent) 60%,transparent)}.qt-settings__body{flex:1;min-height:0;display:flex;flex-direction:column;gap:6px;padding:6px}.qt-settings__search{display:flex;align-items:center;gap:10px;height:36px;padding:0 var(--space-3);border-radius:12px;background:var(--qt-base);color:var(--qt-text-muted);flex-shrink:0}.qt-settings__search input{flex:1;min-width:0;border:none;outline:none;background:transparent;color:var(--qt-text);font-family:inherit;font-size:var(--fs-ui)}.qt-settings__search input:disabled{cursor:not-allowed;color:var(--qt-text-muted)}.qt-settings__search-clear{display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;background:transparent;border:none;border-radius:4px;color:var(--qt-text-muted);cursor:pointer;transition:color .12s ease,background .12s ease}.qt-settings__search-clear:hover{color:var(--qt-text);background:var(--qt-surface-hover)}.qt-settings__group{flex:1;min-height:0;display:flex}.qt-settings__pane{min-height:0;min-width:0}.qt-settings__card{width:100%;height:100%;border-radius:12px;background:var(--qt-base);display:flex;flex-direction:column;overflow:hidden}.qt-settings__content-scroll{flex:1;min-height:0;overflow-y:auto;padding:var(--space-5) var(--space-5)}.qt-settings__separator{width:6px;background:transparent;outline:none}.qt-settings__separator:focus,.qt-settings__separator:focus-visible{outline:none}.qt-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.qt-md{color:var(--qt-text);line-height:1.75;font-size:var(--fs-body)}.qt-md h1,.qt-md h2,.qt-md h3,.qt-md h4{margin:0 0 var(--space-3);color:var(--qt-text);font-weight:600}.qt-md h1{font-size:var(--fs-display)}.qt-md h2{font-size:1.05rem}.qt-md h3{font-size:var(--fs-body)}.qt-md p{margin:0 0 var(--space-3)}.qt-md p:last-child{margin-bottom:0}.qt-md code{background:var(--qt-base);padding:0 3px;border-radius:3px}.qt-md pre{margin:var(--space-3) 0}.qt-md pre code{background:transparent;padding:0}.qt-md strong{color:var(--qt-text);font-weight:600}.qt-md img{max-width:min(100%,480px);height:auto;display:block;margin:var(--space-3) auto}.qt-md-mermaid{margin:var(--space-3) 0;overflow-x:auto}.qt-md-mermaid__dark,.qt-md-mermaid__light{display:none}html[data-theme=mocha] .qt-md-mermaid__dark,html[data-theme=dark] .qt-md-mermaid__dark,:root:not([data-theme=latte]):not([data-theme=light]) .qt-md-mermaid__dark{display:block}html[data-theme=latte] .qt-md-mermaid__light,html[data-theme=light] .qt-md-mermaid__light{display:block}.qt-md-mermaid svg{max-width:100%;height:auto}.qt-md-math{display:block;margin:var(--space-3) 0;text-align:center;overflow-x:auto}.qt-md-math-inline{display:inline}.qt-md-math[data-math-pending],.qt-md-math-inline[data-math-pending]{font-family:var(--font-mono);color:var(--qt-text-muted);opacity:.7}.qt-md-link{color:var(--qt-accent);text-decoration:underline;text-underline-offset:2px}.qt-md-link:hover{color:var(--qt-accent-strong, var(--qt-accent));text-decoration-thickness:2px}.qt-more-btn{background:transparent;border:none;outline:none;color:var(--qt-text-muted);width:26px;height:26px;border-radius:4px;font-size:16px;line-height:1;padding:0;cursor:pointer;transition:color .12s ease}.qt-more-btn:hover{color:var(--qt-text)}.qt-more-btn:focus,.qt-more-btn:focus-visible{outline:none;box-shadow:none}.qt-more-menu{min-width:140px;background:var(--qt-mantle);border:none;border-radius:var(--radius);box-shadow:0 12px 32px #00000052;z-index:40;padding:4px;outline:none}.qt-more-menu__opt{width:100%;background:transparent;border:none;color:var(--qt-text);padding:6px 10px;border-radius:3px;text-align:left;font-family:inherit;font-size:var(--fs-ui);cursor:pointer;transition:background .12s ease}.qt-more-menu__opt:hover:not(:disabled){background:var(--qt-surface-hover)}.qt-more-menu__opt:disabled{color:var(--qt-text-muted);cursor:not-allowed;opacity:.5}.qt-sparkline{display:inline-block;vertical-align:middle;overflow:visible}.qt-sparkline__line{fill:none;stroke:var(--qt-accent, currentColor);stroke-linecap:round;stroke-linejoin:round}.qt-sparkline__dot{fill:var(--qt-accent, currentColor)}.qt-wpm-history{display:flex;flex-direction:column;gap:4px;min-width:180px;font-family:var(--font-mono);font-size:var(--fs-caption)}.qt-wpm-history .qt-sparkline{align-self:center;margin-bottom:4px}.qt-wpm-history__row{display:flex;justify-content:space-between;gap:12px}.qt-wpm-history__label{color:var(--qt-text-muted)}.qt-wpm-history__value{color:var(--qt-text);font-weight:500}.qt-deckcard{display:flex;flex-direction:column;padding:0;background:var(--qt-mantle);border:1px solid transparent;border-radius:12px;color:var(--qt-text);text-align:left;cursor:pointer;transition:transform .12s ease,opacity .12s ease,background .12s ease;min-width:0;min-height:16rem;overflow:hidden;position:relative;word-break:break-word}.qt-deckcard.is-selected{border-color:var(--qt-accent);background:color-mix(in srgb,var(--qt-accent) 8%,var(--qt-mantle))}.qt-deckcard__checkbox{position:absolute;top:10px;left:10px;width:18px;height:18px;border-radius:4px;border:1.5px solid var(--qt-border);background:var(--qt-mantle);color:#fff;font-size:11px;font-weight:700;line-height:1;padding:0;cursor:pointer;display:none;align-items:center;justify-content:center;flex-shrink:0;z-index:3;transition:border-color .12s ease,background .12s ease}.qt-deckcard.is-selection-mode .qt-deckcard__checkbox{display:inline-flex}.qt-deckcard__checkbox:hover{border-color:var(--qt-accent)}.qt-deckcard__checkbox.is-checked{background:var(--qt-accent);border-color:var(--qt-accent)}.qt-deckcard__stamp{position:absolute;right:12px;bottom:8px;padding:3px 10px;border:2px solid var(--qt-green);border-radius:4px;color:var(--qt-green);font-family:var(--font-mono);font-size:10px;font-weight:700;letter-spacing:.15em;transform:rotate(-8deg);background:color-mix(in srgb,var(--qt-green) 8%,transparent);pointer-events:none;-webkit-user-select:none;user-select:none;line-height:1.2;z-index:3}.qt-deckcard:hover{border-color:var(--qt-accent);transform:translateY(-1px)}.qt-deckcard:focus-visible{outline:none;border-color:var(--qt-accent)}.qt-deckcard__done-icon{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:50%;background:color-mix(in srgb,var(--qt-green) 22%,transparent);color:var(--qt-green);font-size:11px;font-weight:700;line-height:1}.qt-deckcard__cover{position:relative;flex:1;display:flex;flex-direction:column;background:linear-gradient(135deg,color-mix(in srgb,var(--qt-accent) 24%,var(--qt-mantle)) 0%,color-mix(in srgb,var(--qt-accent) 8%,var(--qt-mantle)) 50%,var(--qt-mantle) 100%);border-bottom:1px solid var(--qt-border);overflow:hidden}.qt-deckcard__topbar{display:flex;justify-content:space-between;align-items:flex-start;padding:var(--space-3) var(--space-3);padding-bottom:0;z-index:1}.qt-deckcard.is-selection-mode .qt-deckcard__topbar{padding-left:36px}.qt-deckcard__tags{display:flex;gap:6px;flex-wrap:wrap;flex:1;min-width:0}.qt-deckcard__tag{background:var(--qt-base);color:var(--qt-text-muted);padding:3px 10px;border-radius:9999px;font-family:var(--font-mono);font-size:var(--fs-caption);line-height:1;border:1px solid var(--qt-border);max-width:12ch;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.qt-deckcard__tag--more{cursor:help;color:var(--qt-text-muted);opacity:.8}.qt-deckcard__topright{display:flex;align-items:center;gap:4px}.qt-deckcard__check{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:50%;background:color-mix(in srgb,var(--qt-green) 22%,transparent);color:var(--qt-green);font-size:11px;font-weight:700}.qt-deckcard__menuwrap{position:relative}.qt-deckcard__menu-btn{background:transparent;border:none;outline:none;color:var(--qt-text-muted);width:24px;height:24px;border-radius:4px;font-size:16px;line-height:1;padding:0;cursor:pointer;transition:background .12s ease,color .12s ease}.qt-deckcard__menu-btn:focus,.qt-deckcard__menu-btn:focus-visible{outline:none;box-shadow:none}.qt-deckcard__menu-btn:hover{color:var(--qt-text)}.qt-deckcard__menu{position:absolute;top:calc(100% + 4px);right:0;min-width:140px;background:var(--qt-mantle);border:none;border-radius:var(--radius);box-shadow:0 12px 32px #00000052;z-index:20;padding:4px}.qt-deckcard__menu-opt{width:100%;background:transparent;border:none;color:var(--qt-text);padding:6px 10px;border-radius:3px;text-align:left;font-family:inherit;font-size:var(--fs-ui);cursor:pointer;transition:background .12s ease,color .12s ease}.qt-deckcard__menu-opt:hover:not(:disabled){background:var(--qt-surface-hover)}.qt-deckcard__menu-opt:disabled{color:var(--qt-text-muted);cursor:not-allowed;opacity:.5}.qt-deckcard__center{position:relative;flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;padding:var(--space-4) var(--space-4);text-align:center}.qt-deckcard__title{font-size:1.5rem;font-weight:600;color:var(--qt-text);line-height:1.3;letter-spacing:.01em;min-width:0;max-width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.qt-deckcard__count{color:var(--qt-text-muted);font-family:var(--font-mono);font-size:var(--fs-caption)}.qt-deckcard__cover-foot{display:flex;justify-content:space-between;align-items:flex-end;padding:var(--space-3) var(--space-3);padding-top:0;min-height:24px}.qt-deckcard__cover-foot .qt-deckcard__count{padding-left:4px}.qt-deckcard__peak{color:var(--qt-accent);font-family:var(--font-mono);font-size:var(--fs-caption);padding-right:4px;cursor:help}.qt-deckcard__bottom{padding:var(--space-3) var(--space-3);background:var(--qt-mantle);display:flex;flex-direction:column;gap:6px;flex-shrink:0}.qt-deckcard__preview{color:var(--qt-text-muted);font-size:var(--fs-caption);line-height:1.4;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis;height:2.8em;word-break:break-word}.qt-deckcard__meta{display:flex;align-items:center;gap:var(--space-2)}.qt-deckcard__status{padding:2px 8px;border-radius:9999px;font-size:var(--fs-caption);font-family:var(--font-mono);color:var(--qt-text-muted);background:var(--qt-base);border:1px solid var(--qt-border)}.qt-deckcard__status.is-done{color:var(--qt-green);background:color-mix(in srgb,var(--qt-green) 12%,transparent);border-color:color-mix(in srgb,var(--qt-green) 40%,var(--qt-border))}.qt-deckcard.is-done{cursor:not-allowed}.qt-deckcard.is-done:hover{transform:none;border-color:var(--qt-border)}.qt-deckcard.is-done .qt-deckcard__topbar,.qt-deckcard.is-done .qt-deckcard__center,.qt-deckcard.is-done .qt-deckcard__cover-foot,.qt-deckcard.is-done .qt-deckcard__bottom{filter:grayscale(1);opacity:.55}.qt-deckcard.is-done .qt-deckcard__cover{background:var(--qt-mantle)}.qt-deckrow{display:flex;align-items:center;gap:14px;padding:10px 16px 10px 8px;background:transparent;border:1px solid transparent;border-radius:8px;color:var(--qt-text);text-align:left;font-family:inherit;font-size:var(--fs-body);transition:background .12s ease,border-color .12s ease,opacity .12s ease;width:100%;min-width:0;min-height:92px;cursor:pointer;outline:none;word-break:break-word}.qt-deckrow>*{min-width:0}.qt-deckrow:hover,.qt-deckrow:focus-visible{background:var(--qt-surface-hover)}.qt-deckrow.is-selected{background:color-mix(in srgb,var(--qt-accent) 10%,transparent);border-color:var(--qt-accent)}.qt-deckrow__checkbox{width:16px;height:16px;border-radius:3px;border:1.5px solid var(--qt-border);background:transparent;color:#fff;font-size:10px;font-weight:700;line-height:1;padding:0;cursor:pointer;display:none;align-items:center;justify-content:center;flex-shrink:0;transition:border-color .12s ease,background .12s ease}.qt-deckrow.is-selection-mode .qt-deckrow__checkbox{display:inline-flex}.qt-deckrow__checkbox:hover{border-color:var(--qt-accent)}.qt-deckrow__checkbox.is-checked{background:var(--qt-accent);border-color:var(--qt-accent)}.qt-deckrow__thumb{flex-shrink:0;width:64px;height:64px;border-radius:10px;background:linear-gradient(135deg,color-mix(in srgb,var(--qt-accent) 22%,var(--qt-mantle)),var(--qt-mantle));border:1px solid var(--qt-border);display:flex;align-items:center;justify-content:center;color:var(--qt-text);font-family:var(--font-mono);font-size:15px;font-weight:600;letter-spacing:.02em;-webkit-user-select:none;user-select:none}.qt-deckrow__body{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px}.qt-deckrow__line1{display:flex;align-items:center;gap:10px;min-width:0}.qt-deckrow__title{font-weight:600;font-size:var(--fs-body);color:var(--qt-text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;flex:0 1 auto}.qt-deckrow__tags{position:relative;display:flex;gap:4px;overflow:hidden;flex-wrap:nowrap;min-width:0;flex:1 1 auto}.qt-deckrow__tags-measure{position:absolute;visibility:hidden;pointer-events:none;top:0;left:0;display:flex;gap:4px;white-space:nowrap}.qt-deckrow__tag{background:color-mix(in srgb,var(--qt-accent) 14%,transparent);color:var(--qt-accent);padding:1px 8px;border-radius:3px;font-size:var(--fs-caption);font-family:var(--font-mono);line-height:1.4;white-space:nowrap;flex-shrink:0}.qt-deckrow__tag--more{background:transparent;color:var(--qt-text-muted);border:1px solid var(--qt-border);cursor:help}.qt-deckrow__preview{color:var(--qt-text-muted);font-size:var(--fs-caption);line-height:1.4;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.qt-deckrow__line2{display:flex;align-items:center;gap:6px;color:var(--qt-text-muted);font-family:var(--font-mono);font-size:var(--fs-caption);overflow:hidden;white-space:nowrap;min-width:0}.qt-deckrow__line2>span:first-child{overflow:hidden;text-overflow:ellipsis;min-width:0}.qt-deckrow__sep{opacity:.5;flex-shrink:0}.qt-deckrow__stamp{padding:3px 10px;border:2px solid var(--qt-green);border-radius:4px;color:var(--qt-green);font-family:var(--font-mono);font-size:10px;font-weight:700;letter-spacing:.15em;transform:rotate(-6deg);opacity:.85;background:color-mix(in srgb,var(--qt-green) 6%,transparent);pointer-events:none;-webkit-user-select:none;user-select:none;line-height:1.2;flex-shrink:0;align-self:center}.qt-deckrow__menuwrap{position:relative;flex-shrink:0}.qt-deckrow__menu-btn{background:transparent;border:none;outline:none;color:var(--qt-text-muted);width:26px;height:26px;border-radius:4px;font-size:16px;line-height:1;padding:0;cursor:pointer;transition:background .12s ease,color .12s ease}.qt-deckrow__menu-btn:focus,.qt-deckrow__menu-btn:focus-visible{outline:none;box-shadow:none}.qt-deckrow__menu-btn:hover{color:var(--qt-text)}.qt-deckrow__menu{position:absolute;top:calc(100% + 4px);right:0;min-width:140px;background:var(--qt-mantle);border:none;border-radius:var(--radius);box-shadow:0 12px 32px #00000052;z-index:20;padding:4px}.qt-deckrow__menu-opt{width:100%;background:transparent;border:none;color:var(--qt-text);padding:6px 10px;border-radius:3px;text-align:left;font-family:inherit;font-size:var(--fs-ui);cursor:pointer;transition:background .12s ease}.qt-deckrow__menu-opt:hover:not(:disabled){background:var(--qt-surface-hover)}.qt-deckrow__menu-opt:disabled{color:var(--qt-text-muted);cursor:not-allowed;opacity:.5}.qt-deckrow.is-done{cursor:not-allowed}.qt-deckrow.is-done:hover{background:transparent;border-color:transparent}.qt-deckrow.is-done .qt-deckrow__thumb,.qt-deckrow.is-done .qt-deckrow__body{filter:grayscale(1);opacity:.5}.qt-deckrow.is-done .qt-deckrow__stamp{filter:none;opacity:.85}.qt-deckrow__peak{color:var(--qt-accent);cursor:help}.qt-deckcard--dir .qt-deckcard__center{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-2)}.qt-dircard__glyph{color:var(--qt-accent);opacity:.85;display:flex;align-items:center;justify-content:center}.qt-deckcard--dir:hover .qt-dircard__glyph{opacity:1}.qt-deckcard--dir .qt-deckcard__title{text-align:center;width:100%}.qt-deckrow--dir .qt-deckrow__thumb{color:var(--qt-accent);display:flex;align-items:center;justify-content:center}.qt-cardhitcard__type{display:inline-block;padding:3px 8px;border-radius:4px;background:var(--qt-surface-hover);color:var(--qt-text-muted);font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.02em;flex:0 0 auto}.qt-cardhitcard__loc{color:var(--qt-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0}.qt-cardhitcard__pos{color:var(--qt-text-muted);font-family:var(--font-mono);font-size:var(--fs-caption);flex:0 0 auto;margin-left:6px}.qt-cardhit__type{display:inline-block;padding:1px 6px;border-radius:4px;background:var(--qt-surface-hover);color:var(--qt-text-muted);font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.02em;flex:0 0 auto;margin-right:6px}.qt-cardhit__loc{color:var(--qt-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:40ch}.qt-pw{flex:1;min-height:100vh;display:flex;align-items:center;justify-content:center;padding:var(--space-5)}.qt-pw__box{display:flex;flex-direction:column;gap:var(--space-3);width:min(360px,100%);padding:var(--space-5);border:1px solid var(--qt-border);border-radius:var(--radius);background:var(--qt-mantle)}.qt-pw__title{margin:0;font-size:var(--fs-display);color:var(--qt-text);letter-spacing:.05em}.qt-pw__desc{margin:0;color:var(--qt-text-muted);font-size:var(--fs-ui)}.qt-pw__input{height:var(--control-h);padding:0 var(--space-3);border:1px solid var(--qt-border);border-radius:var(--radius);background:var(--qt-base);color:var(--qt-text);font-family:var(--font-mono);font-size:var(--fs-body)}.qt-pw__input:focus{outline:none;border-color:var(--qt-accent)}.qt-pw__error{color:var(--qt-red);font-size:var(--fs-caption)}.qt-pw__hint{margin:0;color:var(--qt-text-muted);font-size:var(--fs-caption);opacity:.7}@keyframes qt-pw-shake{0%,to{transform:translate(0)}20%{transform:translate(-6px)}40%{transform:translate(6px)}60%{transform:translate(-4px)}80%{transform:translate(4px)}}.qt-pw__box--shake{animation:qt-pw-shake .4s ease-in-out}:root{--qt-base: #252528;--qt-mantle: #2b2b2f;--qt-text: #dadada;--qt-text-muted: #b3b3b3;--qt-accent: #7e6ad8;--qt-mauve: #a882ff;--qt-border: #363636;--qt-surface-hover: rgba(255, 255, 255, .067);--qt-green: #44cf6e;--qt-yellow: #e0de71;--qt-peach: #e9973f;--qt-red: #fb464c}:root{--space-1: .25rem;--space-2: .5rem;--space-3: .75rem;--space-4: 1rem;--space-5: 1.125rem;--control-h: 1.75rem;--icon-btn: 1.625rem;--header-h: clamp(40px, 56px - 1.25vw, 44px);--footer-h: clamp(28px, 40px - .85vw, 34px);--search-h: calc(var(--header-h) - .625rem);--gutter: clamp(12px, 3vw, 16px);--radius: 6px}:root{font-size:clamp(13px,9px + 1vw,16px);--fs-caption: .6875rem;--fs-ui: .75rem;--fs-body: .875rem;--fs-title: .875rem;--fs-display: 1.25rem;--font-ui: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;--font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace}*,*:before,*:after{box-sizing:border-box}html,body{margin:0;padding:0;height:100%;overflow:hidden;font-family:var(--font-ui);font-size:var(--fs-body);background:var(--qt-base);color:var(--qt-text);-webkit-font-smoothing:antialiased}*{scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--qt-border) 80%,transparent) transparent}*::-webkit-scrollbar{width:8px;height:8px}*::-webkit-scrollbar-track{background:transparent}*::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--qt-border) 60%,transparent);border-radius:4px;border:2px solid transparent;background-clip:content-box}*::-webkit-scrollbar-thumb:hover{background:color-mix(in srgb,var(--qt-border) 90%,transparent);background-clip:content-box}*::-webkit-scrollbar-corner{background:transparent}#root{height:100%;display:flex;flex-direction:column;overflow:hidden}button{font-family:inherit;font-size:inherit;color:inherit;cursor:pointer}a{color:var(--qt-accent);text-decoration:none}a:hover{text-decoration:underline}kbd{font-family:var(--font-mono)}pre{font-family:var(--font-mono);font-size:var(--fs-body);background:var(--qt-base);border:1px solid var(--qt-border);border-radius:var(--radius);padding:var(--space-3);overflow:auto;line-height:1.5;margin:var(--space-3) 0}code{font-family:var(--font-mono);font-size:.95em;background:var(--qt-base);padding:0 3px;border-radius:3px}pre code{background:transparent;padding:0}.qt-app{display:flex;flex-direction:column;height:100vh;height:100dvh;background:var(--qt-base);overflow:hidden}.qt-empty{color:var(--qt-text-muted);text-align:center;padding:var(--space-5);font-size:var(--fs-body)}.qt-tag{background:color-mix(in srgb,var(--qt-accent) 14%,transparent);color:var(--qt-accent);padding:0 var(--space-2);border-radius:3px;font-size:var(--fs-caption);font-family:var(--font-mono)}.qt-home__grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(200px,45vw),1fr));gap:var(--space-3);min-width:0}.qt-home__list{display:flex;flex-direction:column}.qt-home__virt-grid,.qt-home__virt-list{height:100%;min-height:400px}.qt-card-warning{background:color-mix(in srgb,var(--qt-yellow, #f9e2af) 15%,transparent);border:1px solid color-mix(in srgb,var(--qt-yellow, #f9e2af) 50%,var(--qt-border));color:var(--qt-text);padding:var(--space-2) var(--space-3);border-radius:var(--radius);font-size:var(--fs-caption);margin-bottom:var(--space-2)}.qt-card-warning code{background:color-mix(in srgb,var(--qt-text) 10%,transparent);padding:0 4px;border-radius:3px;margin-left:4px;font-family:var(--font-mono)}.qt-session-done{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-3);padding:var(--space-5)}.qt-session-done__stamp{padding:12px 32px;border:3px solid var(--qt-green);border-radius:8px;color:var(--qt-green);font-family:var(--font-mono);font-size:1.5rem;font-weight:700;letter-spacing:.2em;transform:rotate(-6deg);background:color-mix(in srgb,var(--qt-green) 8%,transparent);animation:qt-stamp-in .4s cubic-bezier(.34,1.56,.64,1)}@keyframes qt-stamp-in{0%{opacity:0;transform:rotate(-30deg) scale(1.6)}to{opacity:1;transform:rotate(-6deg) scale(1)}}.qt-primary{background:var(--qt-accent);color:#fff;padding:0 var(--space-4);height:var(--control-h);border:none;border-radius:var(--radius);font-family:inherit;font-weight:500;font-size:var(--fs-ui);transition:filter .12s ease}.qt-primary:hover{filter:brightness(1.1)}
@@ -1,3 +1,3 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/index-DpS4p4Fg.js","assets/index-zP1tnFzO.js","assets/index-DB9GS9vg.css"])))=>i.map(i=>d[i]);
2
- import{r as l,_ as h,u as g,j as f,C as p,M as m,T as y,a as w}from"./index-zP1tnFzO.js";let o=null,c=null;async function L(){return o||c||(c=h(()=>import("./index-DpS4p4Fg.js"),__vite__mapDeps([0,1,2])).then(async e=>(o=await e.createHighlighter({themes:["github-dark","github-light"],langs:[]}),o)),c)}async function _(e,t){if(!e.getLoadedLanguages().includes(t))try{await e.loadLanguage(t)}catch{}}function x(e){const[t,n]=l.useState(o);return l.useEffect(()=>{if(!e)return;let r=!1;return(async()=>{const s=await L();await _(s,e),r||n(s)})(),()=>{r=!0}},[e]),t}const A=/```(\w+)/;function E(e){const t=e.toLowerCase();return t.includes("typescript")||t.endsWith(".ts")?"typescript":t.includes("python")||t.endsWith(".py")?"python":t.includes("cpp")||t.includes("c++")?"cpp":t.includes("java")&&!t.includes("script")?"java":t.includes("go")?"go":t.includes("rust")||t.endsWith(".rs")?"rust":t.includes("code-c")||t.endsWith(".c")?"c":"javascript"}function j(e,t){if(e){const n=e.match(A);if(n)return n[1]}return E(t)}function k(e,t,n,r){if(!r||!r.getLoadedLanguages().includes(t))return new Array(Array.from(e).length).fill(null);try{const s=r.codeToTokens(e,{lang:t,theme:n}),i=[];for(const u of s.tokens){for(const a of u)for(const d of a.content)i.push(a.color??null);i.push(null)}return!e.endsWith(`
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/index-BbG90BH8.js","assets/index-eEQRUOZD.js","assets/index-B8531CqV.css"])))=>i.map(i=>d[i]);
2
+ import{r as l,_ as h,u as g,j as f,C as p,M as m,T as y,a as w}from"./index-eEQRUOZD.js";let o=null,c=null;async function L(){return o||c||(c=h(()=>import("./index-BbG90BH8.js"),__vite__mapDeps([0,1,2])).then(async e=>(o=await e.createHighlighter({themes:["github-dark","github-light"],langs:[]}),o)),c)}async function _(e,t){if(!e.getLoadedLanguages().includes(t))try{await e.loadLanguage(t)}catch{}}function x(e){const[t,n]=l.useState(o);return l.useEffect(()=>{if(!e)return;let r=!1;return(async()=>{const s=await L();await _(s,e),r||n(s)})(),()=>{r=!0}},[e]),t}const A=/```(\w+)/;function E(e){const t=e.toLowerCase();return t.includes("typescript")||t.endsWith(".ts")?"typescript":t.includes("python")||t.endsWith(".py")?"python":t.includes("cpp")||t.includes("c++")?"cpp":t.includes("java")&&!t.includes("script")?"java":t.includes("go")?"go":t.includes("rust")||t.endsWith(".rs")?"rust":t.includes("code-c")||t.endsWith(".c")?"c":"javascript"}function j(e,t){if(e){const n=e.match(A);if(n)return n[1]}return E(t)}function k(e,t,n,r){if(!r||!r.getLoadedLanguages().includes(t))return new Array(Array.from(e).length).fill(null);try{const s=r.codeToTokens(e,{lang:t,theme:n}),i=[];for(const u of s.tokens){for(const a of u)for(const d of a.content)i.push(a.color??null);i.push(null)}return!e.endsWith(`
3
3
  `)&&i.length>Array.from(e).length&&i.pop(),i}catch{return new Array(Array.from(e).length).fill(null)}}function v(e){var d;const{material:t,card:n}=e,[r]=g(),s=l.useMemo(()=>r?j(n.question,t.filePath):"",[n.question,t.filePath,r]),i=typeof document<"u"&&((d=document.documentElement.getAttribute("data-theme"))!=null&&d.includes("latte"))?"github-light":"github-dark",u=x(r?s:""),a=l.useMemo(()=>r?k(n.answer,s,i,u):void 0,[n.answer,s,i,u,r]);return f.jsx(p,{type:"code",variant:"flow",slots:[{role:"title",content:n.title},n.question?{role:"question",content:f.jsx(m,{source:n.question})}:{role:"question",content:null},{role:"arena",content:f.jsx(y,{...w(e),charColors:a},n.id)}]})}export{v as CodeCard};