vskill 0.5.25 → 0.5.27

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.
@@ -4,8 +4,8 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>Skill Studio</title>
7
- <script type="module" crossorigin src="/assets/index-DbCTMKPM.js"></script>
8
- <link rel="stylesheet" crossorigin href="/assets/index-BJKnEy7-.css">
7
+ <script type="module" crossorigin src="/assets/index-CehwtiFO.js"></script>
8
+ <link rel="stylesheet" crossorigin href="/assets/index-CGNHEtf7.css">
9
9
  </head>
10
10
  <body>
11
11
  <div id="root"></div>
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Quote a YAML value if it contains special characters.
3
+ * Escapes inner backslashes and double quotes, wraps in "...".
4
+ */
5
+ export declare function quoteYAMLValue(value: string): string;
1
6
  /**
2
7
  * Validate a skill name against the agentskills.io standard.
3
8
  * Must be lowercase alphanumeric with hyphens, 1-64 chars, no leading/trailing hyphens.
@@ -10,6 +10,21 @@ const HAS_NAME_RE = /^name:/m;
10
10
  const HAS_DESCRIPTION_RE = /^description:/m;
11
11
  /** Max description length per agentskills.io standard */
12
12
  const MAX_DESCRIPTION_LENGTH = 200;
13
+ /** YAML-special characters that require quoting */
14
+ const YAML_SPECIAL_RE = /[:#\[\]{}'*&!>|"\\]/;
15
+ /** YAML boolean words that need quoting when they start a value */
16
+ const YAML_BOOL_START_RE = /^(true|false|yes|no|on|off|null)\b/i;
17
+ /**
18
+ * Quote a YAML value if it contains special characters.
19
+ * Escapes inner backslashes and double quotes, wraps in "...".
20
+ */
21
+ export function quoteYAMLValue(value) {
22
+ if (!YAML_SPECIAL_RE.test(value) && !YAML_BOOL_START_RE.test(value)) {
23
+ return value;
24
+ }
25
+ const escaped = value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
26
+ return `"${escaped}"`;
27
+ }
13
28
  /**
14
29
  * Validate a skill name against the agentskills.io standard.
15
30
  * Must be lowercase alphanumeric with hyphens, 1-64 chars, no leading/trailing hyphens.
@@ -43,11 +58,11 @@ export function extractDescription(body, skillName) {
43
58
  * Pure function — normalizes CRLF, preserves existing fields, injects missing ones.
44
59
  */
45
60
  export function ensureFrontmatter(content, skillName) {
46
- const normalized = content.replace(/\r\n/g, "\n");
61
+ const normalized = content.replace(/^\uFEFF/, "").replace(/\r\n/g, "\n");
47
62
  const match = normalized.match(FRONTMATTER_RE);
48
63
  if (!match) {
49
64
  const desc = extractDescription(normalized, skillName);
50
- return `---\nname: ${skillName}\ndescription: ${desc}\n---\n\n${normalized}`;
65
+ return `---\nname: ${skillName}\ndescription: ${quoteYAMLValue(desc)}\n---\n\n${normalized}`;
51
66
  }
52
67
  const fmBlock = match[1];
53
68
  const hasName = HAS_NAME_RE.test(fmBlock);
@@ -62,7 +77,7 @@ export function ensureFrontmatter(content, skillName) {
62
77
  if (!hasDescription) {
63
78
  const body = normalized.slice(match[0].length);
64
79
  const desc = extractDescription(body, skillName);
65
- updatedBlock = `${updatedBlock}\ndescription: ${desc}`;
80
+ updatedBlock = `${updatedBlock}\ndescription: ${quoteYAMLValue(desc)}`;
66
81
  }
67
82
  return normalized.replace(FRONTMATTER_RE, `---\n${updatedBlock}\n---`);
68
83
  }
@@ -1 +1 @@
1
- {"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../../src/installer/frontmatter.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,MAAM,cAAc,GAAG,uBAAuB,CAAC;AAE/C,+EAA+E;AAC/E,MAAM,aAAa,GAAG,sCAAsC,CAAC;AAE7D,wEAAwE;AACxE,MAAM,cAAc,GAAG,YAAY,CAAC;AAEpC,kEAAkE;AAClE,MAAM,WAAW,GAAG,SAAS,CAAC;AAE9B,yEAAyE;AACzE,MAAM,kBAAkB,GAAG,gBAAgB,CAAC;AAE5C,yDAAyD;AACzD,MAAM,sBAAsB,GAAG,GAAG,CAAC;AAEnC;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAY;IAClD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,KAAK,CAAC;IACxD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxD,OAAO,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAClC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY,EAAE,SAAiB;IAChE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,OAAO,KAAK,EAAE,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QACxD,OAAO,OAAO,CAAC,MAAM,GAAG,sBAAsB;YAC5C,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,sBAAsB,CAAC;YAC1C,CAAC,CAAC,OAAO,CAAC;IACd,CAAC;IACD,OAAO,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AACtC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAe,EAAE,SAAiB;IAClE,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAClD,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAE/C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,GAAG,kBAAkB,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QACvD,OAAO,cAAc,SAAS,kBAAkB,IAAI,YAAY,UAAU,EAAE,CAAC;IAC/E,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACzB,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC1C,MAAM,cAAc,GAAG,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAExD,IAAI,OAAO,IAAI,cAAc,EAAE,CAAC;QAC9B,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,IAAI,YAAY,GAAG,OAAO,CAAC;IAE3B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,YAAY,GAAG,SAAS,SAAS,KAAK,YAAY,EAAE,CAAC;IACvD,CAAC;IAED,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAC/C,MAAM,IAAI,GAAG,kBAAkB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACjD,YAAY,GAAG,GAAG,YAAY,kBAAkB,IAAI,EAAE,CAAC;IACzD,CAAC;IAED,OAAO,UAAU,CAAC,OAAO,CAAC,cAAc,EAAE,QAAQ,YAAY,OAAO,CAAC,CAAC;AACzE,CAAC"}
1
+ {"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../../src/installer/frontmatter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ export interface MigrationResult {
2
+ migratedCount: number;
3
+ removedCount: number;
4
+ errors: string[];
5
+ }
6
+ export interface NamingResult {
7
+ renamedCount: number;
8
+ errors: string[];
9
+ }
10
+ /**
11
+ * Scan a skill directory for stale flat .md files and restructure them.
12
+ *
13
+ * For each `{name}.md` file found at the root level of skillsDir:
14
+ * 1. If `{name}/SKILL.md` already exists -- delete the flat file (dedup)
15
+ * 2. If `{name}/SKILL.md` does NOT exist -- create the subdirectory,
16
+ * move the content to `{name}/SKILL.md`, run ensureFrontmatter(), delete the flat file
17
+ *
18
+ * Also recurses one level into subdirectories (e.g., sw/) to handle
19
+ * nested stale files like `sw/pm.md` -> `sw/pm/SKILL.md`.
20
+ *
21
+ * Skips: symlinks, directories, files not matching *.md, SKILL.md itself.
22
+ */
23
+ export declare function migrateStaleSkillFiles(skillsDir: string): MigrationResult;
24
+ /**
25
+ * Post-install enforcement: ensure every skill subdirectory has a SKILL.md file.
26
+ *
27
+ * For each subdirectory in skillsDir:
28
+ * - If SKILL.md already exists → skip (idempotent)
29
+ * - Collect .md files, excluding skip-list (README, CHANGELOG, etc.)
30
+ * - If candidates exist, sort alphabetically, take first → rename to SKILL.md with frontmatter
31
+ *
32
+ * Also recurses one level into namespace directories (e.g., sw/).
33
+ */
34
+ export declare function ensureSkillMdNaming(skillsDir: string): NamingResult;
@@ -0,0 +1,223 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Migrate stale flat .md skill files to {name}/SKILL.md subdirectory structure
3
+ // ---------------------------------------------------------------------------
4
+ import { readdirSync, readFileSync, writeFileSync, mkdirSync, unlinkSync, existsSync, lstatSync, } from "node:fs";
5
+ import { join, basename } from "node:path";
6
+ import { ensureFrontmatter } from "./frontmatter.js";
7
+ /**
8
+ * Scan a skill directory for stale flat .md files and restructure them.
9
+ *
10
+ * For each `{name}.md` file found at the root level of skillsDir:
11
+ * 1. If `{name}/SKILL.md` already exists -- delete the flat file (dedup)
12
+ * 2. If `{name}/SKILL.md` does NOT exist -- create the subdirectory,
13
+ * move the content to `{name}/SKILL.md`, run ensureFrontmatter(), delete the flat file
14
+ *
15
+ * Also recurses one level into subdirectories (e.g., sw/) to handle
16
+ * nested stale files like `sw/pm.md` -> `sw/pm/SKILL.md`.
17
+ *
18
+ * Skips: symlinks, directories, files not matching *.md, SKILL.md itself.
19
+ */
20
+ export function migrateStaleSkillFiles(skillsDir) {
21
+ const result = {
22
+ migratedCount: 0,
23
+ removedCount: 0,
24
+ errors: [],
25
+ };
26
+ if (!existsSync(skillsDir))
27
+ return result;
28
+ // Process top-level stale files
29
+ migrateDirLevel(skillsDir, result);
30
+ // Process one level of subdirectories (e.g., sw/)
31
+ let entries;
32
+ try {
33
+ entries = readdirSync(skillsDir);
34
+ }
35
+ catch {
36
+ return result;
37
+ }
38
+ for (const entry of entries) {
39
+ const entryPath = join(skillsDir, entry);
40
+ try {
41
+ const stat = lstatSync(entryPath);
42
+ if (stat.isSymbolicLink())
43
+ continue;
44
+ if (stat.isDirectory()) {
45
+ migrateDirLevel(entryPath, result);
46
+ }
47
+ }
48
+ catch {
49
+ // Skip unreadable entries
50
+ }
51
+ }
52
+ return result;
53
+ }
54
+ /** Files to skip when looking for skill content candidates. */
55
+ const SKIP_FILES = new Set([
56
+ "README.md",
57
+ "CHANGELOG.md",
58
+ "LICENSE.md",
59
+ "FRESHNESS.md",
60
+ "PLUGIN.md",
61
+ ]);
62
+ /**
63
+ * Post-install enforcement: ensure every skill subdirectory has a SKILL.md file.
64
+ *
65
+ * For each subdirectory in skillsDir:
66
+ * - If SKILL.md already exists → skip (idempotent)
67
+ * - Collect .md files, excluding skip-list (README, CHANGELOG, etc.)
68
+ * - If candidates exist, sort alphabetically, take first → rename to SKILL.md with frontmatter
69
+ *
70
+ * Also recurses one level into namespace directories (e.g., sw/).
71
+ */
72
+ export function ensureSkillMdNaming(skillsDir) {
73
+ const result = { renamedCount: 0, errors: [] };
74
+ if (!existsSync(skillsDir))
75
+ return result;
76
+ enforceSkillMdInDir(skillsDir, result);
77
+ // Recurse one level for namespace dirs (e.g., sw/)
78
+ let entries;
79
+ try {
80
+ entries = readdirSync(skillsDir);
81
+ }
82
+ catch {
83
+ return result;
84
+ }
85
+ for (const entry of entries) {
86
+ const entryPath = join(skillsDir, entry);
87
+ try {
88
+ const stat = lstatSync(entryPath);
89
+ if (stat.isSymbolicLink())
90
+ continue;
91
+ if (stat.isDirectory()) {
92
+ enforceSkillMdInDir(entryPath, result);
93
+ }
94
+ }
95
+ catch {
96
+ // Skip unreadable entries
97
+ }
98
+ }
99
+ return result;
100
+ }
101
+ /**
102
+ * Enforce SKILL.md naming in subdirectories of a single directory level.
103
+ */
104
+ function enforceSkillMdInDir(dir, result) {
105
+ let entries;
106
+ try {
107
+ entries = readdirSync(dir);
108
+ }
109
+ catch {
110
+ return;
111
+ }
112
+ for (const entry of entries) {
113
+ const entryPath = join(dir, entry);
114
+ try {
115
+ const stat = lstatSync(entryPath);
116
+ if (stat.isSymbolicLink())
117
+ continue;
118
+ if (!stat.isDirectory())
119
+ continue;
120
+ }
121
+ catch {
122
+ continue;
123
+ }
124
+ // This is a skill subdirectory — check if it has SKILL.md
125
+ const skillMdPath = join(entryPath, "SKILL.md");
126
+ if (existsSync(skillMdPath))
127
+ continue; // Already correct
128
+ // Look for .md candidate files to rename
129
+ let subEntries;
130
+ try {
131
+ subEntries = readdirSync(entryPath);
132
+ }
133
+ catch {
134
+ continue;
135
+ }
136
+ const candidates = subEntries
137
+ .filter((f) => f.endsWith(".md") && !SKIP_FILES.has(f))
138
+ .sort();
139
+ if (candidates.length === 0)
140
+ continue;
141
+ const winner = candidates[0];
142
+ const winnerPath = join(entryPath, winner);
143
+ try {
144
+ const stat = lstatSync(winnerPath);
145
+ if (!stat.isFile() || stat.isSymbolicLink())
146
+ continue;
147
+ const content = readFileSync(winnerPath, "utf-8");
148
+ const skillName = basename(entryPath);
149
+ writeFileSync(skillMdPath, ensureFrontmatter(content, skillName));
150
+ unlinkSync(winnerPath);
151
+ // Remove remaining non-skip .md candidates (they're duplicates)
152
+ for (let i = 1; i < candidates.length; i++) {
153
+ try {
154
+ unlinkSync(join(entryPath, candidates[i]));
155
+ }
156
+ catch {
157
+ // Non-fatal
158
+ }
159
+ }
160
+ result.renamedCount++;
161
+ }
162
+ catch (err) {
163
+ result.errors.push(`Failed to enforce SKILL.md in ${entryPath}: ${err.message}`);
164
+ }
165
+ }
166
+ }
167
+ /**
168
+ * Migrate stale flat .md files within a single directory level.
169
+ */
170
+ function migrateDirLevel(dir, result) {
171
+ let entries;
172
+ try {
173
+ entries = readdirSync(dir);
174
+ }
175
+ catch {
176
+ return;
177
+ }
178
+ for (const entry of entries) {
179
+ // Only process .md files
180
+ if (!entry.endsWith(".md"))
181
+ continue;
182
+ // Skip SKILL.md itself — it's not a stale file
183
+ if (entry === "SKILL.md")
184
+ continue;
185
+ const filePath = join(dir, entry);
186
+ try {
187
+ const stat = lstatSync(filePath);
188
+ // Skip symlinks
189
+ if (stat.isSymbolicLink())
190
+ continue;
191
+ // Skip directories (shouldn't match .md but guard anyway)
192
+ if (!stat.isFile())
193
+ continue;
194
+ }
195
+ catch {
196
+ continue;
197
+ }
198
+ // Derive skill name: "frontend-design.md" -> "frontend-design"
199
+ const skillName = basename(entry, ".md");
200
+ const targetDir = join(dir, skillName);
201
+ const targetSkillMd = join(targetDir, "SKILL.md");
202
+ try {
203
+ if (existsSync(targetSkillMd)) {
204
+ // Both exist — remove stale flat file, preserve existing SKILL.md
205
+ unlinkSync(filePath);
206
+ result.removedCount++;
207
+ }
208
+ else {
209
+ // Migrate: read content, create subdir, write SKILL.md with frontmatter
210
+ const content = readFileSync(filePath, "utf-8");
211
+ const withFrontmatter = ensureFrontmatter(content, skillName);
212
+ mkdirSync(targetDir, { recursive: true });
213
+ writeFileSync(targetSkillMd, withFrontmatter);
214
+ unlinkSync(filePath);
215
+ result.migratedCount++;
216
+ }
217
+ }
218
+ catch (err) {
219
+ result.errors.push(`Failed to migrate ${filePath}: ${err.message}`);
220
+ }
221
+ }
222
+ }
223
+ //# sourceMappingURL=migrate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../src/installer/migrate.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vskill",
3
- "version": "0.5.25",
3
+ "version": "0.5.27",
4
4
  "type": "module",
5
5
  "description": "Secure multi-platform AI skill installer — scan before you install",
6
6
  "bin": {
@@ -1 +0,0 @@
1
- /*! tailwindcss v4.2.1 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--spacing:.25rem;--container-xs:20rem;--container-sm:24rem;--container-md:28rem;--container-lg:32rem;--container-2xl:42rem;--container-3xl:48rem;--container-4xl:56rem;--container-5xl:64rem;--container-6xl:72rem;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-wide:.025em;--tracking-wider:.05em;--tracking-widest:.1em;--leading-relaxed:1.625;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--radius-2xl:1rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.collapse{visibility:collapse}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing) * 0)}.start{inset-inline-start:var(--spacing)}.end{inset-inline-end:var(--spacing)}.top-1{top:calc(var(--spacing) * 1)}.top-1\.5{top:calc(var(--spacing) * 1.5)}.top-8{top:calc(var(--spacing) * 8)}.top-full{top:100%}.right-0{right:calc(var(--spacing) * 0)}.right-1{right:calc(var(--spacing) * 1)}.right-5{right:calc(var(--spacing) * 5)}.bottom-5{bottom:calc(var(--spacing) * 5)}.left-0{left:calc(var(--spacing) * 0)}.z-50{z-index:50}.col-span-1{grid-column:span 1/span 1}.col-span-2{grid-column:span 2/span 2}.col-span-3{grid-column:span 3/span 3}.-mx-2{margin-inline:calc(var(--spacing) * -2)}.mx-4{margin-inline:calc(var(--spacing) * 4)}.mx-auto{margin-inline:auto}.my-4{margin-block:calc(var(--spacing) * 4)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-2\.5{margin-top:calc(var(--spacing) * 2.5)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-3\.5{margin-top:calc(var(--spacing) * 3.5)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-5{margin-top:calc(var(--spacing) * 5)}.mt-6{margin-top:calc(var(--spacing) * 6)}.mb-0\.5{margin-bottom:calc(var(--spacing) * .5)}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-2\.5{margin-bottom:calc(var(--spacing) * 2.5)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-5{margin-bottom:calc(var(--spacing) * 5)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.mb-7{margin-bottom:calc(var(--spacing) * 7)}.mb-8{margin-bottom:calc(var(--spacing) * 8)}.ml-1{margin-left:calc(var(--spacing) * 1)}.ml-2{margin-left:calc(var(--spacing) * 2)}.ml-3{margin-left:calc(var(--spacing) * 3)}.ml-auto{margin-left:auto}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-2{height:calc(var(--spacing) * 2)}.h-2\.5{height:calc(var(--spacing) * 2.5)}.h-3{height:calc(var(--spacing) * 3)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-12{height:calc(var(--spacing) * 12)}.h-14{height:calc(var(--spacing) * 14)}.h-16{height:calc(var(--spacing) * 16)}.h-20{height:calc(var(--spacing) * 20)}.h-24{height:calc(var(--spacing) * 24)}.h-32{height:calc(var(--spacing) * 32)}.h-36{height:calc(var(--spacing) * 36)}.h-48{height:calc(var(--spacing) * 48)}.h-full{height:100%}.h-px{height:1px}.max-h-40{max-height:calc(var(--spacing) * 40)}.max-h-48{max-height:calc(var(--spacing) * 48)}.max-h-64{max-height:calc(var(--spacing) * 64)}.max-h-72{max-height:calc(var(--spacing) * 72)}.max-h-\[500px\]{max-height:500px}.min-h-0{min-height:calc(var(--spacing) * 0)}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-2{width:calc(var(--spacing) * 2)}.w-2\.5{width:calc(var(--spacing) * 2.5)}.w-3{width:calc(var(--spacing) * 3)}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-7{width:calc(var(--spacing) * 7)}.w-8{width:calc(var(--spacing) * 8)}.w-9{width:calc(var(--spacing) * 9)}.w-12{width:calc(var(--spacing) * 12)}.w-14{width:calc(var(--spacing) * 14)}.w-16{width:calc(var(--spacing) * 16)}.w-20{width:calc(var(--spacing) * 20)}.w-28{width:calc(var(--spacing) * 28)}.w-32{width:calc(var(--spacing) * 32)}.w-36{width:calc(var(--spacing) * 36)}.w-48{width:calc(var(--spacing) * 48)}.w-\[340px\]{width:340px}.w-full{width:100%}.max-w-2xl{max-width:var(--container-2xl)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-4xl{max-width:var(--container-4xl)}.max-w-5xl{max-width:var(--container-5xl)}.max-w-6xl{max-width:var(--container-6xl)}.max-w-lg{max-width:var(--container-lg)}.max-w-md{max-width:var(--container-md)}.max-w-sm{max-width:var(--container-sm)}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:calc(var(--spacing) * 0)}.flex-1{flex:1}.flex-shrink-0{flex-shrink:0}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.cursor-pointer{cursor:pointer}.resize{resize:both}.resize-none{resize:none}.resize-y{resize:vertical}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.grid-cols-\[3fr_2fr\]{grid-template-columns:3fr 2fr}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.place-items-center{place-items:center}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0{gap:calc(var(--spacing) * 0)}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-8{gap:calc(var(--spacing) * 8)}:where(.space-y-0\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * .5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * .5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1.5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-8>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 8) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 8) * calc(1 - var(--tw-space-y-reverse)))}.gap-x-3{column-gap:calc(var(--spacing) * 3)}.gap-y-1{row-gap:calc(var(--spacing) * 1)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-\[3px\]{border-radius:3px}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.p-0\.5{padding:calc(var(--spacing) * .5)}.p-1{padding:calc(var(--spacing) * 1)}.p-2{padding:calc(var(--spacing) * 2)}.p-2\.5{padding:calc(var(--spacing) * 2.5)}.p-3{padding:calc(var(--spacing) * 3)}.p-3\.5{padding:calc(var(--spacing) * 3.5)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.p-8{padding:calc(var(--spacing) * 8)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-3\.5{padding-inline:calc(var(--spacing) * 3.5)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.px-8{padding-inline:calc(var(--spacing) * 8)}.px-10{padding-inline:calc(var(--spacing) * 10)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-3\.5{padding-block:calc(var(--spacing) * 3.5)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-5{padding-block:calc(var(--spacing) * 5)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-8{padding-block:calc(var(--spacing) * 8)}.py-12{padding-block:calc(var(--spacing) * 12)}.py-16{padding-block:calc(var(--spacing) * 16)}.py-20{padding-block:calc(var(--spacing) * 20)}.py-px{padding-block:1px}.pt-1{padding-top:calc(var(--spacing) * 1)}.pt-2\.5{padding-top:calc(var(--spacing) * 2.5)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-3\.5{padding-top:calc(var(--spacing) * 3.5)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pr-3{padding-right:calc(var(--spacing) * 3)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-2\.5{padding-bottom:calc(var(--spacing) * 2.5)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pb-4{padding-bottom:calc(var(--spacing) * 4)}.pl-8{padding-left:calc(var(--spacing) * 8)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.text-\[9px\]{font-size:9px}.text-\[10\.5px\]{font-size:10.5px}.text-\[10px\]{font-size:10px}.text-\[11\.5px\]{font-size:11.5px}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.text-\[13px\]{font-size:13px}.text-\[14px\]{font-size:14px}.text-\[15px\]{font-size:15px}.text-\[16px\]{font-size:16px}.text-\[18px\]{font-size:18px}.text-\[20px\]{font-size:20px}.text-\[22px\]{font-size:22px}.text-\[24px\]{font-size:24px}.text-\[28px\]{font-size:28px}.text-\[32px\]{font-size:32px}.text-\[36px\]{font-size:36px}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-pre-wrap{white-space:pre-wrap}.capitalize{text-transform:capitalize}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.line-through{text-decoration-line:line-through}.underline{text-decoration-line:underline}.opacity-0{opacity:0}.opacity-70{opacity:.7}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-100{--tw-duration:.1s;transition-duration:.1s}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.duration-500{--tw-duration:.5s;transition-duration:.5s}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}@media(hover:hover){.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}.hover\:underline:hover{text-decoration-line:underline}}}:root{--surface-0:#0b0d11;--surface-1:#12151b;--surface-2:#1a1e27;--surface-3:#232833;--surface-4:#2c323f;--border-subtle:#ffffff0f;--border-default:#ffffff17;--border-hover:#ffffff24;--border-active:#6383ff73;--text-primary:#e8eaed;--text-secondary:#9aa0ac;--text-tertiary:#5f6672;--accent:#6383ff;--accent-hover:#7e9bff;--accent-muted:#6383ff1f;--green:#34d399;--green-muted:#34d3991f;--red:#f87171;--red-muted:#f871711f;--yellow:#fbbf24;--yellow-muted:#fbbf241f;--orange:#fb923c;--orange-muted:#fb923c1f;--purple:#a78bfa;--purple-muted:#a78bfa1f;--ease-out-expo:cubic-bezier(.16, 1, .3, 1);--ease-spring:cubic-bezier(.34, 1.56, .64, 1)}body{background:var(--surface-0);color:var(--text-primary);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:-apple-system,BlinkMacSystemFont,Inter,Segoe UI,sans-serif}::selection{background:#6383ff4d}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:0 0}::-webkit-scrollbar-thumb{background:var(--surface-4);border-radius:3px}::-webkit-scrollbar-thumb:hover{background:var(--text-tertiary)}@keyframes fade-in{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}@keyframes fade-in-scale{0%{opacity:0;transform:scale(.97)translateY(6px)}to{opacity:1;transform:scale(1)translateY(0)}}@keyframes slide-in-right{0%{opacity:0;transform:translate(12px)}to{opacity:1;transform:translate(0)}}@keyframes shimmer{0%{background-position:-200% 0}to{background-position:200% 0}}@keyframes pulse-ring{0%{opacity:.6;transform:scale(.9)}50%{opacity:.3;transform:scale(1.1)}to{opacity:.6;transform:scale(.9)}}@keyframes spin-slow{to{transform:rotate(360deg)}}@keyframes overlay-in{0%{opacity:0}to{opacity:1}}@keyframes modal-in{0%{opacity:0;transform:scale(.95)translateY(10px)}to{opacity:1;transform:scale(1)translateY(0)}}@keyframes stagger-in{0%{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}@keyframes progress-bar{0%{width:0%}}.animate-fade-in{animation:fade-in .4s var(--ease-out-expo) both}.animate-fade-in-scale{animation:fade-in-scale .35s var(--ease-out-expo) both}.animate-slide-in-right{animation:slide-in-right .3s var(--ease-out-expo) both}.animate-overlay-in{animation:.2s ease-out both overlay-in}.animate-modal-in{animation:modal-in .3s var(--ease-spring) both}.stagger-children>*{animation:stagger-in .4s var(--ease-out-expo) both}.stagger-children>:first-child{animation-delay:0s}.stagger-children>:nth-child(2){animation-delay:40ms}.stagger-children>:nth-child(3){animation-delay:80ms}.stagger-children>:nth-child(4){animation-delay:.12s}.stagger-children>:nth-child(5){animation-delay:.16s}.stagger-children>:nth-child(6){animation-delay:.2s}.stagger-children>:nth-child(7){animation-delay:.24s}.stagger-children>:nth-child(8){animation-delay:.28s}.stagger-children>:nth-child(n+9){animation-delay:.32s}.skeleton{background:linear-gradient(90deg,var(--surface-2) 25%,var(--surface-3) 37%,var(--surface-2) 63%);background-size:200% 100%;border-radius:6px;animation:1.4s ease-in-out infinite shimmer}.glass-card{background:var(--surface-1);border:1px solid var(--border-subtle);transition:border-color .2s ease,box-shadow .2s ease,transform .2s var(--ease-out-expo);border-radius:12px}.glass-card:hover{border-color:var(--border-hover);box-shadow:0 4px 24px #0003}.glass-card-interactive:hover{border-color:var(--border-hover);transform:translateY(-1px);box-shadow:0 4px 24px #00000040}.pill{letter-spacing:.02em;border-radius:9999px;align-items:center;gap:5px;padding:3px 10px;font-size:11px;font-weight:600;line-height:1.4;display:inline-flex}.input-field{background:var(--surface-2);border:1px solid var(--border-default);color:var(--text-primary);border-radius:8px;outline:none;width:100%;padding:8px 12px;font-size:13px;transition:border-color .15s,box-shadow .15s}.input-field:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-muted)}.input-field::placeholder{color:var(--text-tertiary)}.btn{cursor:pointer;white-space:nowrap;border:none;border-radius:8px;outline:none;justify-content:center;align-items:center;gap:6px;padding:7px 16px;font-size:13px;font-weight:500;transition:all .15s;display:inline-flex}.btn:active:not(:disabled){transform:scale(.97)}.btn:disabled{opacity:.4;cursor:not-allowed}.btn-primary{background:var(--accent);color:#fff}.btn-primary:hover:not(:disabled){background:var(--accent-hover)}.btn-purple{background:var(--purple);color:#fff}.btn-purple:hover:not(:disabled){background:#b69dfc}.btn-secondary{background:var(--surface-3);color:var(--text-secondary)}.btn-secondary:hover:not(:disabled){background:var(--surface-4);color:var(--text-primary)}.btn-danger{background:var(--red-muted);color:var(--red)}.btn-danger:hover:not(:disabled){background:#f8717133}.btn-ghost{color:var(--text-secondary);background:0 0;padding:6px 10px}.btn-ghost:hover:not(:disabled){background:var(--surface-3);color:var(--text-primary)}.spinner{border:2px solid var(--surface-4);border-top-color:var(--accent);border-radius:50%;width:16px;height:16px;animation:.6s linear infinite spin-slow}.spinner-lg{border-width:2.5px;width:24px;height:24px}.score-ring{--size:56px;--stroke:4px;width:var(--size);height:var(--size);justify-content:center;align-items:center;display:flex;position:relative}.score-ring svg{position:absolute;top:0;right:0;bottom:0;left:0;transform:rotate(-90deg)}.score-ring circle{fill:none;stroke-width:var(--stroke);stroke-linecap:round}.score-ring .track{stroke:var(--surface-3)}.score-ring .fill{transition:stroke-dashoffset .8s var(--ease-out-expo)}.divide-y>*+*{border-top-color:var(--border-subtle)}@media(max-width:1024px)and (min-width:768px){.studio-grid{grid-template-columns:240px 1px 1fr!important}}@media(max-width:767px){.studio-grid{grid-template-columns:1fr!important}.studio-grid>:nth-child(2),.studio-grid>:nth-child(3){display:none}}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}