better-design 0.8.1 → 0.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -864,16 +864,17 @@ Use these tools for ANY frontend, UI, component, or styling work, without being
864
864
  Tools (exact names): find-design-system, get-design-system-docs, preview-design-system (SHOW in-chat), create-design-system, get-design-system-status (poll after create), get-ui-principle, get-ux-principle, get-review-rules, find-icon-library, find-icons, install-icons, detect-icon-library.
865
865
 
866
866
  ## Build an app (even if the user never says "design" or "brand")
867
- On any "build/make me <app>" request, create the user's BRAND design system FIRST, then build with it:
868
- 1. create-design-system({ prompt }) \u2014 derive the prompt from the app (name, domain, vibe) -> a custom brand (tokens + components). Share the project URL so the user watches it build.
869
- 2. get-design-system-status({ projectId }) \u2014 poll; it SHOWS the generated brand inline.
870
- 3. Build the app with that brand. Brand first, not raw UI.
867
+ On any "build/make me <app>" request, settle the brand FIRST, then build with it:
868
+ 1. find-design-system({ query }) \u2014 derive query from the app. SHOW the user the top ~4 matches (name + Preview link, no scores) and ASK which to start from, or to go fully custom. Don't auto-pick.
869
+ 2. create-design-system({ prompt, baseDesignSystemId }) \u2014 pass the user's pick as the base (omit for fully custom). Share the project URL to watch it build.
870
+ 3. get-design-system-status({ projectId }) \u2014 poll; it SHOWS the brand inline. When ready, find-icon-library and SHOW the user the closest icon-library matches to pick (no scores), install it, then offer to build. Don't stop silently.
871
+ 4. Build the app with that brand. Brand first, not raw UI.
871
872
 
872
873
  ## Building / modifying UI
873
874
  1. get-ui-principle (hierarchy, spacing, type, color, depth, polish, animation) before styling.
874
875
  2. get-ux-principle (forms, nav, errors, dialogs, onboarding, microcopy) before behavior.
875
- 3. Use the project's own tokens/components. Semantic HTML, aria, keyboard nav, WCAG AA.
876
- 4. get-review-rules after; fix every critical/serious issue before presenting.
876
+ 3. Use the project's own tokens/components. Semantic HTML, aria, keyboard nav, WCAG AA. Terse copy.
877
+ 4. get-review-rules after (incl. copy/AI-tell rules); fix every critical/serious issue before presenting.
877
878
 
878
879
  ## Only if the user explicitly names an existing catalog DS
879
880
  Default is create-design-system (above). Just to install a named catalog system: find-design-system(query) -> get-design-system-docs({ designSystemId }) -> run BOTH bash lines (installs globals.css + components into components/ui/; use only their tokens). Icons: detect-icon-library / find-icon-library -> find-icons -> install-icons. Never runtime @iconify/react.
@@ -940,7 +941,7 @@ function createTracking(server, onToolUsage) {
940
941
  function trackSearch(track, tool, capture, start, response, isError = false, errorMessage) {
941
942
  track(
942
943
  tool,
943
- { query: capture.query, topic: capture.topic, topResults: capture.topResults },
944
+ { query: capture.query, topic: capture.topic, topResults: capture.topResults, context: capture.context },
944
945
  {
945
946
  durationMs: Date.now() - start,
946
947
  errorMessage,
@@ -966,7 +967,7 @@ function truncateToTokens(text, maxTokens) {
966
967
 
967
968
  ...(truncated to ~${maxTokens} tokens)`;
968
969
  }
969
- var MAX_OUTPUT_PREVIEW, ICONIFY_FETCH_TIMEOUT_MS, ICONIFY_API_BASE, REGISTRY_BASE_URL, APP_BASE_URL, WIDGET_RESOURCE_DOMAINS, WIDGET_FRAME_DOMAINS, WIDGET_APP_DOMAIN, REQUIREMENTS_MD, ANTI_MOCKUP_MD, BUILD_TARGET_RULE, CODING_HOST_RE, PREVIEW_OUTPUT_SCHEMA, SEARCH_TOOLS;
970
+ var MAX_OUTPUT_PREVIEW, ICONIFY_FETCH_TIMEOUT_MS, ICONIFY_API_BASE, REGISTRY_BASE_URL, APP_BASE_URL, WIDGET_RESOURCE_DOMAINS, WIDGET_FRAME_DOMAINS, WIDGET_APP_DOMAIN, REQUIREMENTS_MD, ANTI_MOCKUP_MD, BUILD_TARGET_RULE, CODING_HOST_RE, PREVIEW_OUTPUT_SCHEMA, CONTEXT_ARG, SEARCH_TOOLS;
970
971
  var init_shared = __esm({
971
972
  "../shared/src/mcp/tools/shared.ts"() {
972
973
  "use strict";
@@ -989,7 +990,11 @@ var init_shared = __esm({
989
990
  - **You can write files into a project and run a terminal** (Claude Code, Cursor, Windsurf, an IDE agent, Claude Desktop with filesystem/shell tools, any checked-out repo): use \`get-design-system-docs\`, run the shadcn install, and build **real React components**. This is the default for any actual project.
990
991
  - **You are in a pure inline chat canvas with NO file writes and NO terminal** (ChatGPT canvas, a Claude.ai chat artifact): use \`get-design-system-html\` and build with the framework-free HTML/CSS kit.
991
992
 
992
- Emitting a single standalone \`.html\` file as "the app" when you could run the React install is a bug: it can't \`import @/components/ui/*\`, drifts from the registry, and discards the real components.`;
993
+ Emitting a single standalone \`.html\` file as "the app" when you could run the React install is a bug: it can't \`import @/components/ui/*\`, drifts from the registry, and discards the real components.
994
+
995
+ Whichever target, keep the output tight: build the screens the user actually asked for (one, unless they asked for more) from the system's own components/tokens, don't pad them with bespoke decorative CSS, and keep your prose to a line or two, no multi-paragraph write-ups or trailing follow-up questions.
996
+
997
+ The UI copy inside the screen follows the same restraint: short headlines (about 6 words), supporting lines about 15 words and at most one per section, no filler adjectives, no exclamation marks, no emoji as icons, and none of the template shapes (gradient hero with an uppercase eyebrow pill, centered three-card feature grid, left-border callout boxes) unless the user asks. After writing the UI, call \`get-review-rules\` and fix every critical/serious issue BEFORE presenting it.`;
993
998
  CODING_HOST_RE = /claude[- ]?code|cursor|windsurf|cline|continue|codeium|codex|zed|vs[- ]?code|vscode|jetbrains|intellij|webstorm|pycharm|goland|rider|neovim|nvim/i;
994
999
  PREVIEW_OUTPUT_SCHEMA = z.object({
995
1000
  status: z.string().describe("completed | error | pending | generating | selected"),
@@ -998,9 +1003,14 @@ Emitting a single standalone \`.html\` file as "the app" when you could run the
998
1003
  previewUrl: z.string().optional().describe("Public, cookieless showcase URL to embed in an iframe (sandboxed hosts can't carry the user's session). Falls back to viewUrl."),
999
1004
  shotUrl: z.string().optional().describe("Real screenshot of the showcase page, for hosts that can't iframe it."),
1000
1005
  installCommand: z.string().optional().describe("shadcn install command, when complete."),
1006
+ installLibrary: z.enum(["base-ui", "radix", "mixed"]).optional().describe("Actual component library flavor installed by installCommand."),
1007
+ installNote: z.string().optional().describe("Important install flavor or fallback note for clients that read only structuredContent."),
1001
1008
  step: z.string().optional().describe("Current generation step, while generating."),
1002
1009
  tokensCss: z.string().describe("CSS custom-property stylesheet for the system's tokens.")
1003
1010
  });
1011
+ CONTEXT_ARG = z.string().max(280).optional().describe(
1012
+ "Optional. One sentence on WHY you are calling this and what the user asked for (e.g. 'adding nav icons for the fintech dashboard'). Used only for usage analytics; does not change the result."
1013
+ );
1004
1014
  SEARCH_TOOLS = /* @__PURE__ */ new Set([
1005
1015
  "find-design-system",
1006
1016
  "get-ui-principle",
@@ -1167,20 +1177,21 @@ Use maxTokens to keep responses focused (recommended: 5000\u201310000).`,
1167
1177
  inputSchema: z2.object({
1168
1178
  topic: z2.string().trim().min(1).max(120).optional().describe("Specific UI topic or alias to load, e.g. spacing, hierarchy, color, depth, animation."),
1169
1179
  query: z2.string().trim().min(1).max(500).optional().describe("Natural language search query to find relevant principles."),
1170
- maxTokens: z2.number().min(500).max(5e4).optional().describe("Maximum tokens to return. Truncates content to fit. Recommended: 5000-10000.")
1180
+ maxTokens: z2.number().min(500).max(5e4).optional().describe("Maximum tokens to return. Truncates content to fit. Recommended: 5000-10000."),
1181
+ context: CONTEXT_ARG
1171
1182
  }),
1172
1183
  annotations: { readOnlyHint: true }
1173
1184
  },
1174
- async ({ topic, query, maxTokens }) => {
1185
+ async ({ topic, query, maxTokens, context }) => {
1175
1186
  const start = Date.now();
1176
1187
  try {
1177
1188
  const { response, capture } = await runPrincipleTool(provider, "ui", "UI", "get-ui-principle", { topic, query, maxTokens });
1178
- return trackSearch(track, "get-ui-principle", capture, start, response);
1189
+ return trackSearch(track, "get-ui-principle", { ...capture, context }, start, response);
1179
1190
  } catch (error) {
1180
1191
  return trackSearch(
1181
1192
  track,
1182
1193
  "get-ui-principle",
1183
- { query, topic, topResults: [] },
1194
+ { query, topic, topResults: [], context },
1184
1195
  start,
1185
1196
  { content: [{ type: "text", text: `Error: ${error instanceof Error ? error.message : "Unknown error"}` }] },
1186
1197
  true,
@@ -1207,20 +1218,21 @@ Use maxTokens to keep responses focused (recommended: 5000\u201310000).`,
1207
1218
  inputSchema: z2.object({
1208
1219
  topic: z2.string().trim().min(1).max(120).optional().describe("Specific UX topic or alias to load, e.g. forms, navigation, notifications, errors, search, onboarding, microcopy, cognitive-laws, psychology."),
1209
1220
  query: z2.string().trim().min(1).max(500).optional().describe("Natural language search query to find relevant UX principles."),
1210
- maxTokens: z2.number().min(500).max(5e4).optional().describe("Maximum tokens to return. Truncates content to fit. Recommended: 5000-10000.")
1221
+ maxTokens: z2.number().min(500).max(5e4).optional().describe("Maximum tokens to return. Truncates content to fit. Recommended: 5000-10000."),
1222
+ context: CONTEXT_ARG
1211
1223
  }),
1212
1224
  annotations: { readOnlyHint: true }
1213
1225
  },
1214
- async ({ topic, query, maxTokens }) => {
1226
+ async ({ topic, query, maxTokens, context }) => {
1215
1227
  const start = Date.now();
1216
1228
  try {
1217
1229
  const { response, capture } = await runPrincipleTool(provider, "ux", "UX", "get-ux-principle", { topic, query, maxTokens });
1218
- return trackSearch(track, "get-ux-principle", capture, start, response);
1230
+ return trackSearch(track, "get-ux-principle", { ...capture, context }, start, response);
1219
1231
  } catch (error) {
1220
1232
  return trackSearch(
1221
1233
  track,
1222
1234
  "get-ux-principle",
1223
- { query, topic, topResults: [] },
1235
+ { query, topic, topResults: [], context },
1224
1236
  start,
1225
1237
  { content: [{ type: "text", text: `Error: ${error instanceof Error ? error.message : "Unknown error"}` }] },
1226
1238
  true,
@@ -1233,9 +1245,9 @@ Use maxTokens to keep responses focused (recommended: 5000\u201310000).`,
1233
1245
  "get-review-rules",
1234
1246
  {
1235
1247
  title: "Get Code Review Rules",
1236
- description: `Retrieves accessibility (WCAG 2.1) and visual design review rules for analyzing code.
1248
+ description: `Retrieves accessibility (WCAG 2.1), visual design, and content review rules for analyzing code.
1237
1249
 
1238
- You MUST call this after writing UI code to self-review your output.
1250
+ You MUST call this after writing UI code to self-review your output, then fix every critical and serious issue BEFORE presenting the result.
1239
1251
 
1240
1252
  **Accessibility (WCAG 2.1):**
1241
1253
  - Critical: Images without alt text, icon buttons without aria-labels, form inputs without labels
@@ -1246,14 +1258,20 @@ You MUST call this after writing UI code to self-review your output.
1246
1258
  - Typography: Mixed fonts, line-height issues, missing fallbacks
1247
1259
  - Color & Contrast: Contrast below 4.5:1, missing hover/focus states
1248
1260
 
1261
+ **Content (generated-UI tells):**
1262
+ - Walls of text, overwritten copy, filler adjectives, emoji used as icons
1263
+ - Microcopy details: pluralization, improvised unit glyphs, empty states without a next action
1264
+ - Template layouts: gradient hero + eyebrow pill, left-border callout boxes
1265
+
1249
1266
  Use maxTokens to keep responses focused (recommended: 5000\u201310000).`,
1250
1267
  inputSchema: z2.object({
1251
- category: z2.enum(["accessibility", "visual-design", "all"]).optional().describe("Filter rules by category (defaults to 'all')"),
1252
- maxTokens: z2.number().min(500).max(5e4).optional().describe("Maximum tokens to return. Truncates content to fit. Recommended: 5000\u201310000.")
1268
+ category: z2.enum(["accessibility", "visual-design", "content", "all"]).optional().describe("Filter rules by category (defaults to 'all')"),
1269
+ maxTokens: z2.number().min(500).max(5e4).optional().describe("Maximum tokens to return. Truncates content to fit. Recommended: 5000\u201310000."),
1270
+ context: CONTEXT_ARG
1253
1271
  }),
1254
1272
  annotations: { readOnlyHint: true }
1255
1273
  },
1256
- async ({ category = "all", maxTokens }) => {
1274
+ async ({ category = "all", maxTokens, context }) => {
1257
1275
  const start = Date.now();
1258
1276
  try {
1259
1277
  const rules = await provider.getReviewRules(category);
@@ -1262,7 +1280,7 @@ Use maxTokens to keep responses focused (recommended: 5000\u201310000).`,
1262
1280
  return trackSearch(
1263
1281
  track,
1264
1282
  "get-review-rules",
1265
- { query: category, topic: category, topResults },
1283
+ { query: category, topic: category, topResults, context },
1266
1284
  start,
1267
1285
  { content: [{ type: "text", text: "No review rules found." }] }
1268
1286
  );
@@ -1289,7 +1307,7 @@ Start at 100. Minimum score is 0.
1289
1307
  return trackSearch(
1290
1308
  track,
1291
1309
  "get-review-rules",
1292
- { query: category, topic: category, topResults },
1310
+ { query: category, topic: category, topResults, context },
1293
1311
  start,
1294
1312
  { content: [{ type: "text", text }] }
1295
1313
  );
@@ -1297,7 +1315,7 @@ Start at 100. Minimum score is 0.
1297
1315
  return trackSearch(
1298
1316
  track,
1299
1317
  "get-review-rules",
1300
- { query: category, topic: category, topResults: [] },
1318
+ { query: category, topic: category, topResults: [], context },
1301
1319
  start,
1302
1320
  { content: [{ type: "text", text: `Error: ${error instanceof Error ? error.message : "Unknown error"}` }] },
1303
1321
  true,
@@ -1449,9 +1467,9 @@ import { z as z3 } from "zod";
1449
1467
  function registerIconTools({ server, provider, tracked, track }) {
1450
1468
  const iconLibraryConfig = {
1451
1469
  title: "Find Icon Library",
1452
- description: `Search for icon libraries matching a design style or personality using semantic search.
1470
+ description: `Search for icon libraries matching a design style or personality using semantic search, and return the closest matches.
1453
1471
 
1454
- Use this to find an icon library that matches your design system's personality:
1472
+ After a design system is ready, call this and SHOW the user the closest matches (name + style, no scores), then ask which they want, don't auto-pick. Use this to find an icon library that matches your design system's personality:
1455
1473
  - Style traits (minimal, bold, rounded, sharp, outlined, filled)
1456
1474
  - Mood (friendly, professional, playful, serious, warm, elegant)
1457
1475
  - Use case (consumer, enterprise, developer, dashboard, mobile)
@@ -1480,19 +1498,16 @@ Examples:
1480
1498
  );
1481
1499
  }
1482
1500
  const formatted = results.map((r) => {
1501
+ const browseUrl = `https://icon-sets.iconify.design/${r.prefix}/`;
1483
1502
  const lines = [
1484
- `**ID:** ${r.id}`,
1485
- `**Name:** ${r.name}`,
1486
- `**Prefix:** ${r.prefix}`,
1487
- `**Style:** ${r.tags.join(", ")}`
1503
+ `### [${r.name}](${browseUrl})`,
1504
+ `_${r.tags.join(", ")}_ \xB7 id: \`${r.id}\` \xB7 prefix: \`${r.prefix}\``
1488
1505
  ];
1489
1506
  if (r.variants?.length) {
1490
- lines.push(`**Variants:** ${r.variants.join(", ")}`);
1491
- lines.push(`**Default Variant:** ${r.defaultVariant || r.variants[0]}`);
1507
+ lines.push(`Variants: ${r.variants.join(", ")} (default: ${r.defaultVariant || r.variants[0]})`);
1492
1508
  }
1493
- lines.push(`**Match Score:** ${r.matchScore}%`);
1494
1509
  return lines.join("\n");
1495
- }).join("\n\n----------\n\n");
1510
+ }).join("\n\n");
1496
1511
  return trackSearch(
1497
1512
  track,
1498
1513
  toolName,
@@ -1501,9 +1516,9 @@ Examples:
1501
1516
  {
1502
1517
  content: [{
1503
1518
  type: "text",
1504
- text: `# Matching Icon Libraries
1519
+ text: `# Matching icon libraries
1505
1520
 
1506
- Use the prefix with Iconify: \`<Icon icon="prefix:icon-name" />\`
1521
+ Show these to the user as options (no scores), keeping each name as its clickable link so they can open it and SEE the icons before choosing. Ask which fits their brand, don't auto-pick. Once they choose, use \`find-icons\` + \`install-icons\` with that library's \`id\`. (Iconify usage: \`<Icon icon="prefix:icon-name" />\`.)
1507
1522
 
1508
1523
  ---
1509
1524
 
@@ -1623,13 +1638,14 @@ If \`components/icons/index.ts\` already exists in the project, MERGE the new ex
1623
1638
  names: z3.array(z3.string()).min(1).describe("Icon names to install. May be bare (e.g. 'home') or prefixed (e.g. 'tabler:home')."),
1624
1639
  targetDir: z3.string().optional().describe("Directory inside the project to write into. Defaults to 'components/icons'."),
1625
1640
  format: z3.enum(["tsx", "svg"]).optional().describe("Output format. 'tsx' (default) generates React components; 'svg' generates raw .svg files."),
1626
- variant: z3.string().optional().describe("Optional library variant (e.g. 'outline', 'filled').")
1641
+ variant: z3.string().optional().describe("Optional library variant (e.g. 'outline', 'filled')."),
1642
+ context: CONTEXT_ARG
1627
1643
  }),
1628
1644
  annotations: { readOnlyHint: true }
1629
1645
  },
1630
- async ({ libraryId, names, targetDir, format, variant }) => tracked(
1646
+ async ({ libraryId, names, targetDir, format, variant, context }) => tracked(
1631
1647
  "install-icons",
1632
- { libraryId, count: names.length, format: format ?? "tsx" },
1648
+ { libraryId, count: names.length, format: format ?? "tsx", context },
1633
1649
  async () => {
1634
1650
  try {
1635
1651
  const dirResult = validateTargetDir(targetDir);
@@ -1827,11 +1843,12 @@ Returns either:
1827
1843
  - The locked library info + installed icon list, with a hint to call install-icons using that libraryId, OR
1828
1844
  - A "no library detected" response, prompting the agent to call find-icon-library normally.`,
1829
1845
  inputSchema: z3.object({
1830
- manifestContent: z3.string().optional().describe("Contents of the project's components/icons/.library.json file, if it exists. The agent should attempt to read this file from disk and pass it here. If the file doesn't exist or can't be read, omit this field.")
1846
+ manifestContent: z3.string().optional().describe("Contents of the project's components/icons/.library.json file, if it exists. The agent should attempt to read this file from disk and pass it here. If the file doesn't exist or can't be read, omit this field."),
1847
+ context: CONTEXT_ARG
1831
1848
  }),
1832
1849
  annotations: { readOnlyHint: true }
1833
1850
  },
1834
- async ({ manifestContent }) => tracked("detect-icon-library", { hasManifest: Boolean(manifestContent) }, async () => {
1851
+ async ({ manifestContent, context }) => tracked("detect-icon-library", { hasManifest: Boolean(manifestContent), context }, async () => {
1835
1852
  if (!manifestContent || !manifestContent.trim()) {
1836
1853
  return { content: [{ type: "text", text: "No `.library.json` manifest found. Proceed by calling `find-icon-library` to pick a library, then `install-icons` to scaffold icons. The library you pick will be locked for subsequent installs." }] };
1837
1854
  }
@@ -1896,6 +1913,15 @@ Map each UI need to the installed component BEFORE writing markup:
1896
1913
 
1897
1914
  Read a component's source from \`components/ui/\` to learn its props/exports. Use only
1898
1915
  the design tokens in \`app/globals.css\`; never invent colors, spacing, or radii.
1916
+
1917
+ **Copy and layout restraint.** The words inside the UI are part of the design system
1918
+ too. Write the fewest words that carry the meaning: headlines about 6 words, one short
1919
+ supporting line per section, no filler adjectives (seamless, effortless, powerful), no
1920
+ exclamation marks, never emoji as icons or status indicators (use the DS's icon library
1921
+ or \`badge\` variants). Skip the generated-template shapes unless explicitly requested:
1922
+ gradient hero with an uppercase eyebrow pill, centered three-card feature grid,
1923
+ left-border callout boxes, walls of text. After writing UI, self-review with
1924
+ \`get-review-rules\` and fix every critical/serious issue before presenting.
1899
1925
  `;
1900
1926
  DS_ESLINT_CONFIG = `// Better Design \u2014 design-system guardrail (flat ESLint config fragment).
1901
1927
  // Flags raw HTML primitives in feature code when the installed DS ships an
@@ -1965,6 +1991,55 @@ After wiring, \`npm run lint\` flags raw primitives in feature code (warnings; b
1965
1991
  function fence(lang, body) {
1966
1992
  return "```" + lang + "\n" + body + "\n```";
1967
1993
  }
1994
+ function parseDecls(body) {
1995
+ const out = /* @__PURE__ */ new Map();
1996
+ for (const decl of body.split(";")) {
1997
+ const i = decl.indexOf(":");
1998
+ if (i === -1) continue;
1999
+ const prop = decl.slice(0, i).trim();
2000
+ const val = decl.slice(i + 1).trim();
2001
+ if (!prop || !val) continue;
2002
+ if (prop.startsWith("--") && val.replace(/\s+/g, "") === `var(${prop})`) continue;
2003
+ out.set(prop, val);
2004
+ }
2005
+ return out;
2006
+ }
2007
+ function hoistAtRules(css) {
2008
+ const atRules = [];
2009
+ const grab = (m) => {
2010
+ atRules.push(m.trim());
2011
+ return "";
2012
+ };
2013
+ const body = css.replace(/@charset\s+(['"]).*?\1\s*;/g, grab).replace(/@import\s+url\(\s*(['"]).*?\1\s*\)[^;]*;/g, grab).replace(/@import\s+(['"]).*?\1[^;]*;/g, grab);
2014
+ return { atRules, body };
2015
+ }
2016
+ function compactTokensCss(css) {
2017
+ const noComments = css.replace(/\/\*[\s\S]*?\*\//g, "");
2018
+ const { atRules, body } = hoistAtRules(noComments);
2019
+ const header = atRules.length ? atRules.join("\n") + "\n\n" : "";
2020
+ const merged = /* @__PURE__ */ new Map();
2021
+ for (const m of body.matchAll(/:root\s*\{([^}]*)\}/g)) {
2022
+ for (const [prop, val] of parseDecls(m[1])) merged.set(prop, val);
2023
+ }
2024
+ if (merged.size === 0) return (header + body.trim()).trim() || css.trim();
2025
+ const rootBody = [...merged].map(([p, v]) => ` ${p}: ${v};`).join("\n");
2026
+ let darkOut = "";
2027
+ const darkMatch = body.match(/\.dark\s*\{([^}]*)\}/);
2028
+ if (darkMatch) {
2029
+ const diff = [...parseDecls(darkMatch[1])].filter(([p, v]) => merged.get(p) !== v);
2030
+ if (diff.length) {
2031
+ const darkBody = diff.map(([p, v]) => ` ${p}: ${v};`).join("\n");
2032
+ darkOut = `
2033
+ .dark {
2034
+ ${darkBody}
2035
+ }`;
2036
+ }
2037
+ }
2038
+ const rest = body.replace(/:root\s*\{[^}]*\}/g, "").replace(/\.dark\s*\{[^}]*\}/g, "").replace(/\n{2,}/g, "\n").trim();
2039
+ return `${header}:root {
2040
+ ${rootBody}
2041
+ }${darkOut}${rest ? "\n\n" + rest : ""}`;
2042
+ }
1968
2043
  function buildDsHtmlKit({ name, tokensCss, viewUrl, componentKit }) {
1969
2044
  const materialCss = componentKit?.css?.trim();
1970
2045
  return [
@@ -1975,7 +2050,7 @@ function buildDsHtmlKit({ name, tokensCss, viewUrl, componentKit }) {
1975
2050
  "## 1. Design tokens (paste first)",
1976
2051
  "These are the system's actual oklch tokens, fonts, radius and shadow scale.",
1977
2052
  "",
1978
- fence("css", tokensCss.trim()),
2053
+ fence("css", compactTokensCss(tokensCss)),
1979
2054
  "",
1980
2055
  "## 2. Component CSS (paste second)",
1981
2056
  "Token-driven, vanilla CSS. No Tailwind, no build step.",
@@ -1994,10 +2069,20 @@ function buildDsHtmlKit({ name, tokensCss, viewUrl, componentKit }) {
1994
2069
  fence("html", DS_KIT_EXAMPLE_HTML),
1995
2070
  "",
1996
2071
  "## How to use",
1997
- "- Put all CSS blocks in a single `<style>` tag (tokens first, real material last).",
2072
+ "- Paste every CSS block above VERBATIM into a single `<style>` tag (tokens first, real material last). Copy the blocks exactly, never retype or summarize them from memory: retyped CSS silently drops this system's material.",
1998
2073
  '- Wrap your app in `<div class="ds">` so the base type/color apply.',
1999
- "- Components: `ds-btn` (`ds-btn-primary|secondary|outline|ghost`, `ds-btn-sm|lg`), `ds-input` / `ds-textarea` / `ds-select` + `ds-label`, `ds-card` (`ds-card-header|body|footer`, `ds-card-title|desc`), `ds-badge` (`ds-badge-primary|outline`), `ds-alert`, `ds-avatar`, `ds-divider`, layout helpers `ds-row` / `ds-field` / `ds-container`.",
2074
+ "- Components: `ds-btn` (`ds-btn-primary|secondary|outline|ghost`, `ds-btn-sm|lg`), `ds-input` / `ds-textarea` / `ds-select` + `ds-label`, `ds-card` (`ds-card-header|body|footer`, `ds-card-title|desc`), `ds-badge` (`ds-badge-primary|outline|safe|warn|danger|unknown|verified`), `ds-alert`, `ds-avatar`, `ds-divider`, layout helpers `ds-row` / `ds-field` / `ds-container`.",
2075
+ '- Status colors: the `ds-badge-safe|warn|danger|unknown|verified` classes are colour modifiers, so add them ALONGSIDE the base `ds-badge`, for example `<span class="ds-badge ds-badge-safe">Sesame-free</span>`. They map to the system\'s own status tokens. Reach for these instead of hand-writing a colored badge from a raw token.',
2076
+ "- Filters, toggles and any tappable pill use `ds-chip` (or `ds-btn`) rendered as a real `<button>`, never a `ds-badge` span. Badges are read-only status labels.",
2077
+ '- Make the mock WORK, not just render: wire a few lines of vanilla JS so every control has a VISIBLE EFFECT. Filter chips toggle `aria-pressed` (the kit styles `ds-chip[aria-pressed="true"]` as selected) AND actually filter: tag each list item with `data-tags="..."` and hide items that do not match the pressed chips. Search inputs filter the list on `input`. A control that changes nothing reads as broken.',
2078
+ "- Custom classes are for LAYOUT only (position, spacing, grid). Never restyle a `ds-*` component's geometry or surface (border-radius, borders, shadows, fills) \u2014 those carry this system's identity. If a component looks wrong, use a different `ds-*` component, do not reshape it.",
2079
+ "- Cards in a grid must stay aligned: the kit pins `ds-card-footer` to the card bottom so rows of cards keep equal footer lines even when a badge row wraps \u2014 do not override that. Keep wrap-prone rows (badges, chips) in the same slot on every card so nothing reads as misaligned.",
2000
2080
  "- Build any layout you want with these tokens, do not invent new colors. For the full React component set in a real project, use `get-design-system-docs` instead.",
2081
+ "",
2082
+ "## Keep it tight",
2083
+ "Build the screens the user actually asked for (one, unless they asked for more) and compose the `ds-*` components above. Do not hand-roll a pile of bespoke decorative CSS (illustrative art, faux maps, gradients, glassmorphism panels, radial-glow backgrounds): reach for the `ds-*` classes and these tokens first. Skip a long write-up: ship the artifact with a one-line note, no multi-paragraph explanation or trailing follow-up questions.",
2084
+ "",
2085
+ HTML_KIT_CONDUCT_MD,
2001
2086
  ...componentKit?.excluded?.length ? [
2002
2087
  "",
2003
2088
  "## Not in this kit (use the real components)",
@@ -2007,13 +2092,13 @@ function buildDsHtmlKit({ name, tokensCss, viewUrl, componentKit }) {
2007
2092
  Full live showcase: ${viewUrl}` : ""
2008
2093
  ].join("\n");
2009
2094
  }
2010
- var DS_KIT_CSS, DS_KIT_EXAMPLE_HTML;
2095
+ var DS_KIT_CSS, DS_KIT_EXAMPLE_HTML, HTML_KIT_CONDUCT_MD;
2011
2096
  var init_html_kit = __esm({
2012
2097
  "../shared/src/mcp/html-kit.ts"() {
2013
2098
  "use strict";
2014
2099
  DS_KIT_CSS = `*,*::before,*::after{box-sizing:border-box}
2015
2100
  :where(.ds){font-family:var(--font-sans,ui-sans-serif,system-ui,sans-serif);color:var(--foreground,oklch(0.2 0 0));background:var(--background,oklch(1 0 0));line-height:1.5}
2016
- .ds h1,.ds h2,.ds h3,.ds h4{font-family:var(--font-serif,var(--font-sans,ui-sans-serif));font-weight:600;margin:0 0 .5em;color:var(--foreground,oklch(0.2 0 0))}
2101
+ .ds h1,.ds h2,.ds h3,.ds h4{font-family:inherit;font-weight:600;margin:0 0 .5em;color:var(--foreground,oklch(0.2 0 0))}
2017
2102
  .ds a{color:var(--primary,oklch(0.45 0.15 264));text-decoration:none}
2018
2103
  .ds a:hover{text-decoration:underline}
2019
2104
  .ds p{margin:0 0 1em}
@@ -2034,16 +2119,17 @@ var init_html_kit = __esm({
2034
2119
 
2035
2120
  /* Form fields */
2036
2121
  .ds-label{display:block;font-size:.8125rem;font-weight:500;margin-bottom:.4rem;color:var(--foreground,oklch(0.2 0 0))}
2037
- .ds-input,.ds-textarea,.ds-select{width:100%;font:inherit;font-size:.875rem;padding:.55rem .75rem;border-radius:var(--radius-md,calc(var(--radius,0.5rem) - 2px));border:1px solid var(--input,var(--border,oklch(0.85 0 0)));background:var(--background,oklch(1 0 0));color:var(--foreground,oklch(0.2 0 0));box-shadow:var(--shadow-2xs,none)}
2122
+ .ds-input,.ds-textarea,.ds-select{width:100%;font:inherit;font-size:.875rem;padding:.55rem .75rem;border-radius:var(--radius-lg,var(--radius,0.5rem));border:1px solid var(--border,oklch(0.85 0 0));background:var(--input,var(--background,oklch(1 0 0)));color:var(--foreground,oklch(0.2 0 0));box-shadow:var(--shadow-inset,var(--shadow-2xs,none));transition:border-color .15s,box-shadow .15s}
2038
2123
  .ds-input::placeholder,.ds-textarea::placeholder{color:var(--muted-foreground,oklch(0.6 0 0))}
2039
- .ds-input:focus,.ds-textarea:focus,.ds-select:focus{outline:2px solid var(--ring,var(--primary,oklch(0.45 0.15 264)));outline-offset:1px;border-color:transparent}
2124
+ .ds-input:hover,.ds-textarea:hover,.ds-select:hover{border-color:color-mix(in oklab,var(--foreground,oklch(0.2 0 0)) 20%,transparent)}
2125
+ .ds-input:focus,.ds-textarea:focus,.ds-select:focus{outline:none;border-color:var(--ring,var(--primary,oklch(0.45 0.15 264)));box-shadow:var(--shadow-inset,0 0 0 0 transparent),0 0 0 2px color-mix(in oklab,var(--ring,var(--primary,oklch(0.45 0.15 264))) 35%,transparent)}
2040
2126
  .ds-textarea{min-height:5rem;resize:vertical}
2041
2127
 
2042
2128
  /* Card */
2043
- .ds-card{background:var(--card,var(--background,oklch(1 0 0)));color:var(--card-foreground,var(--foreground,oklch(0.2 0 0)));border:1px solid var(--border,oklch(0.9 0 0));border-radius:var(--radius-xl,calc(var(--radius,0.5rem) + 4px));box-shadow:var(--shadow-glass,var(--shadow-md,var(--shadow-sm,none)));overflow:hidden}
2129
+ .ds-card{display:flex;flex-direction:column;background:var(--card,var(--background,oklch(1 0 0)));color:var(--card-foreground,var(--foreground,oklch(0.2 0 0)));border:1px solid var(--border,oklch(0.9 0 0));border-radius:var(--radius-xl,calc(var(--radius,0.5rem) + 4px));box-shadow:var(--shadow-glass,var(--shadow-md,var(--shadow-sm,none)));overflow:hidden}
2044
2130
  .ds-card-header{padding:1.1rem 1.25rem .5rem}
2045
2131
  .ds-card-body{padding:.5rem 1.25rem 1.1rem}
2046
- .ds-card-footer{padding:.9rem 1.25rem;border-top:1px solid var(--border,oklch(0.92 0 0));display:flex;gap:.5rem;align-items:center}
2132
+ .ds-card-footer{margin-top:auto;padding:.9rem 1.25rem;border-top:1px solid var(--border,oklch(0.92 0 0));display:flex;gap:.5rem;align-items:center}
2047
2133
  .ds-card-title{font-size:1.05rem;margin:0 0 .25rem}
2048
2134
  .ds-card-desc{font-size:.875rem;color:var(--muted-foreground,oklch(0.55 0 0));margin:0}
2049
2135
 
@@ -2051,6 +2137,11 @@ var init_html_kit = __esm({
2051
2137
  .ds-badge{display:inline-flex;align-items:center;font-size:.6875rem;font-weight:600;padding:.15rem .55rem;border-radius:999px;background:var(--secondary,oklch(0.96 0 0));color:var(--secondary-foreground,oklch(0.25 0 0));line-height:1.4}
2052
2138
  .ds-badge-primary{background:var(--primary,oklch(0.45 0.15 264));color:var(--primary-foreground,oklch(1 0 0))}
2053
2139
  .ds-badge-outline{background:transparent;border:1px solid var(--border,oklch(0.85 0 0));color:var(--foreground,oklch(0.2 0 0))}
2140
+ .ds-badge-safe{background:var(--pop-green,oklch(0.92 0.06 150));color:var(--pop-green-foreground,oklch(0.42 0.11 152))}
2141
+ .ds-badge-warn{background:var(--pop-orange,oklch(0.93 0.05 40));color:var(--pop-orange-foreground,oklch(0.52 0.18 35))}
2142
+ .ds-badge-danger{background:var(--destructive,oklch(0.58 0.22 32));color:var(--destructive-foreground,oklch(0.99 0 0))}
2143
+ .ds-badge-unknown{background:var(--pop-yellow,oklch(0.95 0.06 92));color:var(--pop-yellow-foreground,oklch(0.5 0.1 75))}
2144
+ .ds-badge-verified{background:var(--pop-blue,oklch(0.92 0.045 245));color:var(--pop-blue-foreground,oklch(0.48 0.14 252))}
2054
2145
 
2055
2146
  /* Alert */
2056
2147
  .ds-alert{border:1px solid var(--border,oklch(0.9 0 0));border-radius:var(--radius-lg,var(--radius,0.5rem));padding:.9rem 1rem;background:var(--card,var(--background,oklch(1 0 0)));color:var(--card-foreground,var(--foreground,oklch(0.2 0 0)));font-size:.875rem}
@@ -2085,7 +2176,10 @@ var init_html_kit = __esm({
2085
2176
  .ds-table th{font-weight:600;color:var(--muted-foreground,oklch(0.5 0 0));font-size:.6875rem;text-transform:uppercase;letter-spacing:.04em}
2086
2177
 
2087
2178
  /* Chip / keyboard key */
2088
- .ds-chip{display:inline-flex;align-items:center;gap:.35rem;font-size:.8125rem;padding:.3rem .7rem;border-radius:999px;border:1px solid var(--border,oklch(0.88 0 0));background:var(--background,oklch(1 0 0));color:var(--foreground,oklch(0.2 0 0))}
2179
+ .ds-chip{display:inline-flex;align-items:center;gap:.35rem;font:inherit;font-size:.8125rem;padding:.3rem .7rem;border-radius:999px;border:1px solid var(--border,oklch(0.88 0 0));background:var(--background,oklch(1 0 0));color:var(--foreground,oklch(0.2 0 0));cursor:pointer;transition:background .15s,border-color .15s}
2180
+ .ds-chip:hover{background:var(--accent,oklch(0.96 0 0))}
2181
+ .ds-chip:focus-visible{outline:2px solid var(--ring,var(--primary,oklch(0.45 0.15 264)));outline-offset:2px}
2182
+ .ds-chip[aria-pressed="true"]{background:var(--primary,oklch(0.45 0.15 264));color:var(--primary-foreground,oklch(1 0 0));border-color:var(--primary,oklch(0.45 0.15 264))}
2089
2183
  .ds-kbd{font-family:var(--font-mono,ui-monospace,monospace);font-size:.75rem;padding:.1rem .4rem;border-radius:var(--radius-sm,4px);border:1px solid var(--border,oklch(0.85 0 0));background:var(--muted,oklch(0.97 0 0));color:var(--foreground,oklch(0.2 0 0))}
2090
2184
 
2091
2185
  /* Selection adopts the accent, matching the real systems */
@@ -2118,6 +2212,20 @@ var init_html_kit = __esm({
2118
2212
  </div>
2119
2213
  </div>
2120
2214
  </div>`;
2215
+ HTML_KIT_CONDUCT_MD = [
2216
+ "## Write the UI copy like a designer",
2217
+ "The words inside the screen are part of the design, and overwriting them is the fastest generated-content tell:",
2218
+ "- Headlines: about 6 words max. Supporting line: about 15 words, at most one per section.",
2219
+ "- No filler adjectives (seamless, effortless, powerful), no exclamation marks.",
2220
+ "- Never use emoji as icons or status indicators. Use the badge/status classes this system ships or an inline SVG.",
2221
+ '- Sweat the small strings: pluralize counts (1 bet, 2 bets), no redundant self-labels ("You (you)"), spell out abbreviations, units and currency as real words or an inline icon ("1,000 coins", never an improvised glyph like "\xA7"), and empty states name the next action.',
2222
+ "- Skip the template-landing-page shapes unless the user asks for them: gradient hero with an uppercase eyebrow pill, centered three-card feature grid, left-border callout boxes.",
2223
+ "- Status surfaces (warnings, banners) use the system's semantic status tokens; if it ships none, use a bordered card on the default surface, never a chart/data-viz tint. Selected rows get a clearly contrasting treatment (primary fill or a visible edge), not the hover token's faint tint.",
2224
+ "",
2225
+ "## Before you show it (mandatory)",
2226
+ '1. Self-check the artifact: every input has a visible `<label>`; selected/active states use the role-appropriate native or ARIA state (`aria-pressed` for toggle buttons, `aria-selected` for tabs/options, native `checked` for checkboxes, `aria-current` for current links) plus a visible non-color cue; interactive tiles look pressable (border, hover, pressed state); focus stays visible (never remove an outline without a replacement); toasts and status text use `role="status"`; every color comes from the system\'s tokens; radii come from the `--radius` scale.',
2227
+ "2. Call `get-review-rules` (category `all`) and fix every critical and serious issue it reports BEFORE presenting the artifact to the user."
2228
+ ].join("\n");
2121
2229
  }
2122
2230
  });
2123
2231
 
@@ -2130,6 +2238,1325 @@ var init_preview_widget_sdk_generated = __esm({
2130
2238
  }
2131
2239
  });
2132
2240
 
2241
+ // ../shared/src/mcp/tw-extracted.generated.ts
2242
+ var TW_STATIC_EXTRACTED, TW_VARIANTS_EXTRACTED;
2243
+ var init_tw_extracted_generated = __esm({
2244
+ "../shared/src/mcp/tw-extracted.generated.ts"() {
2245
+ "use strict";
2246
+ TW_STATIC_EXTRACTED = {
2247
+ "ring-0": "--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)",
2248
+ "ring-1": "--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)",
2249
+ "ring-2": "--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)",
2250
+ "ring-4": "--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)",
2251
+ "ring-8": "--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(8px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)",
2252
+ "ring-offset-0": "--tw-ring-offset-width:0px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)",
2253
+ "ring-offset-1": "--tw-ring-offset-width:1px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)",
2254
+ "ring-offset-2": "--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)",
2255
+ "ring-offset-4": "--tw-ring-offset-width:4px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)",
2256
+ "ring-inset": "--tw-ring-inset:inset",
2257
+ "ring-offset-background": "--tw-ring-offset-color:var(--background)",
2258
+ "opacity-0": "opacity:0",
2259
+ "opacity-5": "opacity:0.05",
2260
+ "opacity-10": "opacity:0.1",
2261
+ "opacity-15": "opacity:0.15",
2262
+ "opacity-20": "opacity:0.2",
2263
+ "opacity-25": "opacity:0.25",
2264
+ "opacity-30": "opacity:0.3",
2265
+ "opacity-35": "opacity:0.35",
2266
+ "opacity-40": "opacity:0.4",
2267
+ "opacity-45": "opacity:0.45",
2268
+ "opacity-50": "opacity:0.5",
2269
+ "opacity-55": "opacity:0.55",
2270
+ "opacity-60": "opacity:0.6",
2271
+ "opacity-65": "opacity:0.65",
2272
+ "opacity-70": "opacity:0.7",
2273
+ "opacity-75": "opacity:0.75",
2274
+ "opacity-80": "opacity:0.8",
2275
+ "opacity-85": "opacity:0.85",
2276
+ "opacity-90": "opacity:0.9",
2277
+ "opacity-95": "opacity:0.95",
2278
+ "opacity-100": "opacity:1",
2279
+ "transform": "transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)",
2280
+ "transform-gpu": "transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)",
2281
+ "transform-none": "transform:none",
2282
+ "rotate-0": "rotate:0deg",
2283
+ "rotate-45": "rotate:45deg",
2284
+ "rotate-90": "rotate:90deg",
2285
+ "rotate-180": "rotate:180deg",
2286
+ "scale-0": "--tw-scale-x:0%;--tw-scale-y:0%;--tw-scale-z:0%;scale:var(--tw-scale-x) var(--tw-scale-y)",
2287
+ "scale-50": "--tw-scale-x:50%;--tw-scale-y:50%;--tw-scale-z:50%;scale:var(--tw-scale-x) var(--tw-scale-y)",
2288
+ "scale-75": "--tw-scale-x:75%;--tw-scale-y:75%;--tw-scale-z:75%;scale:var(--tw-scale-x) var(--tw-scale-y)",
2289
+ "scale-90": "--tw-scale-x:90%;--tw-scale-y:90%;--tw-scale-z:90%;scale:var(--tw-scale-x) var(--tw-scale-y)",
2290
+ "scale-95": "--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x) var(--tw-scale-y)",
2291
+ "scale-100": "--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x) var(--tw-scale-y)",
2292
+ "scale-105": "--tw-scale-x:105%;--tw-scale-y:105%;--tw-scale-z:105%;scale:var(--tw-scale-x) var(--tw-scale-y)",
2293
+ "scale-110": "--tw-scale-x:110%;--tw-scale-y:110%;--tw-scale-z:110%;scale:var(--tw-scale-x) var(--tw-scale-y)",
2294
+ "scale-125": "--tw-scale-x:125%;--tw-scale-y:125%;--tw-scale-z:125%;scale:var(--tw-scale-x) var(--tw-scale-y)",
2295
+ "scale-150": "--tw-scale-x:150%;--tw-scale-y:150%;--tw-scale-z:150%;scale:var(--tw-scale-x) var(--tw-scale-y)",
2296
+ "transition-none": "transition-property:none",
2297
+ "transition": "transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(0.4,0,0.2,1);transition-duration:150ms",
2298
+ "transition-all": "transition-property:all;transition-timing-function:cubic-bezier(0.4,0,0.2,1);transition-duration:150ms",
2299
+ "transition-colors": "transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(0.4,0,0.2,1);transition-duration:150ms",
2300
+ "transition-transform": "transition-property:transform;transition-timing-function:cubic-bezier(0.4,0,0.2,1);transition-duration:150ms",
2301
+ "transition-opacity": "transition-property:opacity;transition-timing-function:cubic-bezier(0.4,0,0.2,1);transition-duration:150ms",
2302
+ "transition-shadow": "transition-property:box-shadow;transition-timing-function:cubic-bezier(0.4,0,0.2,1);transition-duration:150ms",
2303
+ "delay-0": "transition-delay:0s",
2304
+ "delay-75": "animation-delay:75ms;--tw-animation-delay:75ms",
2305
+ "delay-100": "animation-delay:0.1s;--tw-animation-delay:0.1s",
2306
+ "delay-150": "animation-delay:0.15s;--tw-animation-delay:0.15s",
2307
+ "delay-200": "animation-delay:0.2s;--tw-animation-delay:0.2s",
2308
+ "delay-300": "animation-delay:0.3s;--tw-animation-delay:0.3s",
2309
+ "delay-500": "animation-delay:0.5s;--tw-animation-delay:0.5s",
2310
+ "delay-700": "animation-delay:0.7s;--tw-animation-delay:0.7s",
2311
+ "delay-1000": "animation-delay:1s;--tw-animation-delay:1s",
2312
+ "duration-0": "transition-duration:0s",
2313
+ "duration-75": "animation-duration:75ms;--tw-animation-duration:75ms",
2314
+ "duration-100": "animation-duration:0.1s;--tw-animation-duration:0.1s",
2315
+ "duration-150": "animation-duration:0.15s;--tw-animation-duration:0.15s",
2316
+ "duration-200": "animation-duration:0.2s;--tw-animation-duration:0.2s",
2317
+ "duration-300": "animation-duration:0.3s;--tw-animation-duration:0.3s",
2318
+ "duration-500": "animation-duration:0.5s;--tw-animation-duration:0.5s",
2319
+ "duration-700": "animation-duration:0.7s;--tw-animation-duration:0.7s",
2320
+ "duration-1000": "animation-duration:1s;--tw-animation-duration:1s",
2321
+ "ease-linear": "transition-timing-function:linear",
2322
+ "ease-in": "transition-timing-function:cubic-bezier(0.4,0,1,1)",
2323
+ "ease-out": "transition-timing-function:cubic-bezier(0,0,0.2,1)",
2324
+ "ease-in-out": "transition-timing-function:cubic-bezier(0.4,0,0.2,1)",
2325
+ "animate-none": "animation:none",
2326
+ "animate-spin": "animation:spin 1s linear infinite",
2327
+ "animate-ping": "animation:ping 1s cubic-bezier(0, 0, 0.2, 1) infinite",
2328
+ "animate-pulse": "animation:pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite",
2329
+ "animate-bounce": "animation:bounce 1s infinite",
2330
+ "will-change-auto": "will-change:auto",
2331
+ "will-change-scroll": "will-change:scroll-position",
2332
+ "will-change-contents": "will-change:contents",
2333
+ "will-change-transform": "will-change:transform",
2334
+ "sr-only": "position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border-width:0",
2335
+ "not-sr-only": "position:static;width:auto;height:auto;padding:0;margin:0;overflow:visible;clip-path:none;white-space:normal",
2336
+ "animate-in": "animation:enter var(--tw-animation-duration,var(--tw-duration,0.15s)) var(--tw-ease,ease) var(--tw-animation-delay,0s) var(--tw-animation-iteration-count,1) var(--tw-animation-direction,normal) var(--tw-animation-fill-mode,none)",
2337
+ "animate-out": "animation:exit var(--tw-animation-duration,var(--tw-duration,0.15s)) var(--tw-ease,ease) var(--tw-animation-delay,0s) var(--tw-animation-iteration-count,1) var(--tw-animation-direction,normal) var(--tw-animation-fill-mode,none)",
2338
+ "fade-in": "--tw-enter-opacity:0",
2339
+ "fade-out": "--tw-exit-opacity:0",
2340
+ "zoom-in": "--tw-enter-scale:0",
2341
+ "zoom-out": "--tw-exit-scale:0",
2342
+ "spin-in": "--tw-enter-rotate:30deg",
2343
+ "spin-out": "--tw-exit-rotate:30deg",
2344
+ "-spin-in": "--tw-enter-rotate:-30deg",
2345
+ "-spin-out": "--tw-exit-rotate:-30deg",
2346
+ "blur-in": "--tw-enter-blur:20px",
2347
+ "blur-out": "--tw-exit-blur:20px",
2348
+ "slide-in-from-top": "--tw-enter-translate-y:-100%",
2349
+ "slide-in-from-bottom": "--tw-enter-translate-y:100%",
2350
+ "slide-in-from-left": "--tw-enter-translate-x:-100%",
2351
+ "slide-in-from-right": "--tw-enter-translate-x:100%",
2352
+ "slide-out-to-top": "--tw-exit-translate-y:-100%",
2353
+ "slide-out-to-bottom": "--tw-exit-translate-y:100%",
2354
+ "slide-out-to-left": "--tw-exit-translate-x:-100%",
2355
+ "slide-out-to-right": "--tw-exit-translate-x:100%",
2356
+ "running": "animation-play-state:running",
2357
+ "paused": "animation-play-state:paused",
2358
+ "accordion-down": "animation:accordion-down var(--tw-animation-duration,var(--tw-duration,0.2s)) var(--tw-ease,ease-out) var(--tw-animation-delay,0s) var(--tw-animation-iteration-count,1) var(--tw-animation-direction,normal) var(--tw-animation-fill-mode,none)",
2359
+ "accordion-up": "animation:accordion-up var(--tw-animation-duration,var(--tw-duration,0.2s)) var(--tw-ease,ease-out) var(--tw-animation-delay,0s) var(--tw-animation-iteration-count,1) var(--tw-animation-direction,normal) var(--tw-animation-fill-mode,none)",
2360
+ "collapsible-down": "animation:collapsible-down var(--tw-animation-duration,var(--tw-duration,0.2s)) var(--tw-ease,ease-out) var(--tw-animation-delay,0s) var(--tw-animation-iteration-count,1) var(--tw-animation-direction,normal) var(--tw-animation-fill-mode,none)",
2361
+ "collapsible-up": "animation:collapsible-up var(--tw-animation-duration,var(--tw-duration,0.2s)) var(--tw-ease,ease-out) var(--tw-animation-delay,0s) var(--tw-animation-iteration-count,1) var(--tw-animation-direction,normal) var(--tw-animation-fill-mode,none)",
2362
+ "caret-blink": "animation:caret-blink 1.25s ease-out infinite",
2363
+ "grid": "display:grid",
2364
+ "inline-grid": "display:inline-grid",
2365
+ "grid-cols-1": "grid-template-columns:repeat(1,minmax(0,1fr))",
2366
+ "grid-cols-2": "grid-template-columns:repeat(2,minmax(0,1fr))",
2367
+ "grid-cols-3": "grid-template-columns:repeat(3,minmax(0,1fr))",
2368
+ "grid-cols-4": "grid-template-columns:repeat(4,minmax(0,1fr))",
2369
+ "grid-cols-5": "grid-template-columns:repeat(5,minmax(0,1fr))",
2370
+ "grid-cols-6": "grid-template-columns:repeat(6,minmax(0,1fr))",
2371
+ "grid-cols-7": "grid-template-columns:repeat(7,minmax(0,1fr))",
2372
+ "grid-cols-12": "grid-template-columns:repeat(12,minmax(0,1fr))",
2373
+ "grid-rows-1": "grid-template-rows:repeat(1,minmax(0,1fr))",
2374
+ "grid-rows-2": "grid-template-rows:repeat(2,minmax(0,1fr))",
2375
+ "grid-rows-3": "grid-template-rows:repeat(3,minmax(0,1fr))",
2376
+ "grid-rows-4": "grid-template-rows:repeat(4,minmax(0,1fr))",
2377
+ "grid-rows-6": "grid-template-rows:repeat(6,minmax(0,1fr))",
2378
+ "col-span-1": "grid-column:span 1/span 1",
2379
+ "col-span-2": "grid-column:span 2/span 2",
2380
+ "col-span-3": "grid-column:span 3/span 3",
2381
+ "col-span-4": "grid-column:span 4/span 4",
2382
+ "col-span-5": "grid-column:span 5/span 5",
2383
+ "col-span-6": "grid-column:span 6/span 6",
2384
+ "col-span-full": "grid-column:1/-1",
2385
+ "col-auto": "grid-column:auto",
2386
+ "col-start-1": "grid-column-start:1",
2387
+ "col-start-2": "grid-column-start:2",
2388
+ "col-start-3": "grid-column-start:3",
2389
+ "col-start-4": "grid-column-start:4",
2390
+ "col-start-5": "grid-column-start:5",
2391
+ "col-start-6": "grid-column-start:6",
2392
+ "col-start-7": "grid-column-start:7",
2393
+ "col-start-auto": "grid-column-start:auto",
2394
+ "col-end-1": "grid-column-end:1",
2395
+ "col-end-2": "grid-column-end:2",
2396
+ "col-end-3": "grid-column-end:3",
2397
+ "col-end-4": "grid-column-end:4",
2398
+ "col-end-5": "grid-column-end:5",
2399
+ "col-end-6": "grid-column-end:6",
2400
+ "col-end-7": "grid-column-end:7",
2401
+ "col-end-auto": "grid-column-end:auto",
2402
+ "row-span-1": "grid-row:span 1/span 1",
2403
+ "row-span-2": "grid-row:span 2/span 2",
2404
+ "row-span-3": "grid-row:span 3/span 3",
2405
+ "row-span-full": "grid-row:1/-1",
2406
+ "row-auto": "grid-row:auto",
2407
+ "row-start-1": "grid-row-start:1",
2408
+ "row-start-2": "grid-row-start:2",
2409
+ "row-start-3": "grid-row-start:3",
2410
+ "row-start-4": "grid-row-start:4",
2411
+ "row-start-5": "grid-row-start:5",
2412
+ "row-start-6": "grid-row-start:6",
2413
+ "row-start-auto": "grid-row-start:auto",
2414
+ "row-end-1": "grid-row-end:1",
2415
+ "row-end-2": "grid-row-end:2",
2416
+ "row-end-3": "grid-row-end:3",
2417
+ "row-end-4": "grid-row-end:4",
2418
+ "row-end-auto": "grid-row-end:auto",
2419
+ "auto-cols-auto": "grid-auto-columns:auto",
2420
+ "auto-cols-min": "grid-auto-columns:min-content",
2421
+ "auto-cols-max": "grid-auto-columns:max-content",
2422
+ "auto-cols-fr": "grid-auto-columns:minmax(0,1fr)",
2423
+ "auto-rows-auto": "grid-auto-rows:auto",
2424
+ "auto-rows-min": "grid-auto-rows:min-content",
2425
+ "auto-rows-max": "grid-auto-rows:max-content",
2426
+ "auto-rows-fr": "grid-auto-rows:minmax(0,1fr)",
2427
+ "grid-flow-row": "grid-auto-flow:row",
2428
+ "grid-flow-col": "grid-auto-flow:column",
2429
+ "grid-flow-dense": "grid-auto-flow:dense",
2430
+ "grid-flow-row-dense": "grid-auto-flow:row dense",
2431
+ "grid-flow-col-dense": "grid-auto-flow:column dense",
2432
+ "place-items-auto": "place-items:auto",
2433
+ "place-items-start": "place-items:start",
2434
+ "place-items-end": "place-items:end",
2435
+ "place-items-center": "place-items:center",
2436
+ "place-items-baseline": "place-items:baseline",
2437
+ "place-items-stretch": "place-items:stretch stretch",
2438
+ "place-content-auto": "place-content:auto",
2439
+ "place-content-start": "place-content:start",
2440
+ "place-content-end": "place-content:end",
2441
+ "place-content-center": "place-content:center",
2442
+ "place-content-between": "place-content:space-between",
2443
+ "place-content-around": "place-content:space-around",
2444
+ "place-content-evenly": "place-content:space-evenly",
2445
+ "place-content-stretch": "place-content:stretch",
2446
+ "place-self-auto": "place-self:auto",
2447
+ "place-self-start": "place-self:start",
2448
+ "place-self-end": "place-self:end",
2449
+ "place-self-center": "place-self:center",
2450
+ "place-self-baseline": "place-self:baseline",
2451
+ "place-self-stretch": "place-self:stretch stretch",
2452
+ "bg-none": "background-image:none",
2453
+ "bg-cover": "background-size:cover",
2454
+ "bg-contain": "background-size:contain",
2455
+ "bg-center": "background-position:center",
2456
+ "bg-bottom": "background-position:bottom",
2457
+ "bg-left": "background-position:left",
2458
+ "bg-left-bottom": "background-position:left bottom",
2459
+ "bg-left-top": "background-position:left top",
2460
+ "bg-right": "background-position:right",
2461
+ "bg-right-bottom": "background-position:right bottom",
2462
+ "bg-right-top": "background-position:right top",
2463
+ "bg-top": "background-position:top",
2464
+ "bg-no-repeat": "background-repeat:no-repeat",
2465
+ "bg-repeat": "background-repeat:repeat",
2466
+ "bg-repeat-x": "background-repeat:repeat-x",
2467
+ "bg-repeat-y": "background-repeat:repeat-y",
2468
+ "bg-fixed": "background-attachment:fixed",
2469
+ "bg-local": "background-attachment:local",
2470
+ "bg-scroll": "background-attachment:scroll",
2471
+ "bg-clip-border": "background-clip:border-box",
2472
+ "bg-clip-padding": "background-clip:padding-box",
2473
+ "bg-clip-text": "background-clip:text",
2474
+ "bg-origin-border": "background-origin:border-box",
2475
+ "bg-gradient-to-t": "--tw-gradient-position:to top in oklab;background-image:linear-gradient(var(--tw-gradient-stops))",
2476
+ "bg-gradient-to-tr": "--tw-gradient-position:to top right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))",
2477
+ "bg-gradient-to-r": "--tw-gradient-position:to right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))",
2478
+ "bg-gradient-to-br": "--tw-gradient-position:to bottom right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))",
2479
+ "bg-gradient-to-b": "--tw-gradient-position:to bottom in oklab;background-image:linear-gradient(var(--tw-gradient-stops))",
2480
+ "bg-gradient-to-bl": "--tw-gradient-position:to bottom left in oklab;background-image:linear-gradient(var(--tw-gradient-stops))",
2481
+ "bg-gradient-to-l": "--tw-gradient-position:to left in oklab;background-image:linear-gradient(var(--tw-gradient-stops))",
2482
+ "bg-gradient-to-tl": "--tw-gradient-position:to top left in oklab;background-image:linear-gradient(var(--tw-gradient-stops))",
2483
+ "blur": "--tw-blur:blur(0px);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,)",
2484
+ "blur-sm": "--tw-blur:blur(4px);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,)",
2485
+ "blur-md": "--tw-blur:blur(12px);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,)",
2486
+ "blur-lg": "--tw-blur:blur(20px);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,)",
2487
+ "blur-xl": "--tw-blur:blur(40px);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,)",
2488
+ "blur-2xl": "--tw-blur:blur(80px);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,)",
2489
+ "brightness-50": "--tw-brightness:brightness(50%);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,)",
2490
+ "brightness-75": "--tw-brightness:brightness(75%);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,)",
2491
+ "brightness-100": "--tw-brightness:brightness(100%);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,)",
2492
+ "brightness-125": "--tw-brightness:brightness(125%);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,)",
2493
+ "brightness-150": "--tw-brightness:brightness(150%);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,)",
2494
+ "brightness-200": "--tw-brightness:brightness(200%);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,)",
2495
+ "contrast": "--tw-contrast:contrast(100%);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,)",
2496
+ "contrast-50": "--tw-contrast:contrast(50%);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,)",
2497
+ "contrast-75": "--tw-contrast:contrast(75%);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,)",
2498
+ "contrast-100": "--tw-contrast:contrast(100%);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,)",
2499
+ "contrast-125": "--tw-contrast:contrast(125%);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,)",
2500
+ "contrast-150": "--tw-contrast:contrast(150%);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,)",
2501
+ "contrast-200": "--tw-contrast:contrast(200%);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,)",
2502
+ "saturate": "--tw-saturate:saturate(100%);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,)",
2503
+ "saturate-0": "--tw-saturate:saturate(0%);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,)",
2504
+ "saturate-50": "--tw-saturate:saturate(50%);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,)",
2505
+ "saturate-75": "--tw-saturate:saturate(75%);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,)",
2506
+ "saturate-100": "--tw-saturate:saturate(100%);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,)",
2507
+ "saturate-125": "--tw-saturate:saturate(125%);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,)",
2508
+ "saturate-150": "--tw-saturate:saturate(150%);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,)",
2509
+ "saturate-200": "--tw-saturate:saturate(200%);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,)",
2510
+ "grayscale": "--tw-grayscale:grayscale(100%);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,)",
2511
+ "grayscale-0": "--tw-grayscale:grayscale(0%);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,)",
2512
+ "invert": "--tw-invert:invert(100%);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,)",
2513
+ "invert-0": "--tw-invert:invert(0%);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,)",
2514
+ "sepia": "--tw-sepia:sepia(100%);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,)",
2515
+ "sepia-0": "--tw-sepia:sepia(0%);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,)",
2516
+ "hue-rotate-0": "--tw-hue-rotate:hue-rotate(0deg);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,)",
2517
+ "hue-rotate-15": "--tw-hue-rotate:hue-rotate(15deg);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,)",
2518
+ "hue-rotate-30": "--tw-hue-rotate:hue-rotate(30deg);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,)",
2519
+ "hue-rotate-45": "--tw-hue-rotate:hue-rotate(45deg);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,)",
2520
+ "hue-rotate-60": "--tw-hue-rotate:hue-rotate(60deg);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,)",
2521
+ "hue-rotate-90": "--tw-hue-rotate:hue-rotate(90deg);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,)",
2522
+ "hue-rotate-180": "--tw-hue-rotate:hue-rotate(180deg);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,)",
2523
+ "backdrop-blur": "--tw-backdrop-blur:blur(0px);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)",
2524
+ "backdrop-blur-sm": "--tw-backdrop-blur:blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)",
2525
+ "backdrop-blur-md": "--tw-backdrop-blur:blur(12px);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)",
2526
+ "backdrop-blur-lg": "--tw-backdrop-blur:blur(20px);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)",
2527
+ "backdrop-blur-xl": "--tw-backdrop-blur:blur(40px);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)",
2528
+ "backdrop-blur-2xl": "--tw-backdrop-blur:blur(80px);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)",
2529
+ "backdrop-brightness": "--tw-backdrop-brightness:brightness(100%);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)",
2530
+ "backdrop-brightness-50": "--tw-backdrop-brightness:brightness(50%);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)",
2531
+ "backdrop-brightness-75": "--tw-backdrop-brightness:brightness(75%);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)",
2532
+ "backdrop-brightness-100": "--tw-backdrop-brightness:brightness(100%);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)",
2533
+ "backdrop-contrast": "--tw-backdrop-contrast:contrast(100%);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)",
2534
+ "backdrop-contrast-50": "--tw-backdrop-contrast:contrast(50%);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)",
2535
+ "backdrop-contrast-75": "--tw-backdrop-contrast:contrast(75%);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)",
2536
+ "backdrop-contrast-100": "--tw-backdrop-contrast:contrast(100%);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)",
2537
+ "backdrop-saturate": "--tw-backdrop-saturate:saturate(100%);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)",
2538
+ "backdrop-saturate-50": "--tw-backdrop-saturate:saturate(50%);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)",
2539
+ "backdrop-saturate-75": "--tw-backdrop-saturate:saturate(75%);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)",
2540
+ "backdrop-saturate-100": "--tw-backdrop-saturate:saturate(100%);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)",
2541
+ "backdrop-grayscale": "--tw-backdrop-grayscale:grayscale(100%);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)",
2542
+ "backdrop-grayscale-0": "--tw-backdrop-grayscale:grayscale(0%);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)",
2543
+ "backdrop-invert": "--tw-backdrop-invert:invert(100%);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)",
2544
+ "backdrop-invert-0": "--tw-backdrop-invert:invert(0%);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)",
2545
+ "backdrop-sepia": "--tw-backdrop-sepia:sepia(100%);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)",
2546
+ "backdrop-sepia-0": "--tw-backdrop-sepia:sepia(0%);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)",
2547
+ "backdrop-opacity-10": "--tw-backdrop-opacity:opacity(10%);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)",
2548
+ "backdrop-opacity-20": "--tw-backdrop-opacity:opacity(20%);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)",
2549
+ "backdrop-opacity-30": "--tw-backdrop-opacity:opacity(30%);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)",
2550
+ "backdrop-opacity-40": "--tw-backdrop-opacity:opacity(40%);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)",
2551
+ "backdrop-opacity-50": "--tw-backdrop-opacity:opacity(50%);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)",
2552
+ "backdrop-hue-rotate-0": "--tw-backdrop-hue-rotate:hue-rotate(0deg);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)",
2553
+ "backdrop-hue-rotate-90": "--tw-backdrop-hue-rotate:hue-rotate(90deg);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)",
2554
+ "backdrop-hue-rotate-180": "--tw-backdrop-hue-rotate:hue-rotate(180deg);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)",
2555
+ "object-cover": "object-fit:cover",
2556
+ "object-contain": "object-fit:contain",
2557
+ "object-fill": "object-fit:fill",
2558
+ "object-center": "object-position:center",
2559
+ "aspect-square": "aspect-ratio:1",
2560
+ "aspect-video": "aspect-ratio:16/9",
2561
+ "aspect-auto": "aspect-ratio:auto",
2562
+ "align-middle": "vertical-align:middle",
2563
+ "align-top": "vertical-align:top",
2564
+ "align-bottom": "vertical-align:bottom",
2565
+ "align-baseline": "vertical-align:baseline",
2566
+ "list-none": "list-style-type:none",
2567
+ "list-disc": "list-style-type:disc",
2568
+ "list-decimal": "list-style-type:decimal",
2569
+ "appearance-none": "appearance:none",
2570
+ "resize-none": "resize:none",
2571
+ "resize-x": "resize:horizontal",
2572
+ "resize-y": "resize:vertical",
2573
+ "resize": "resize:both",
2574
+ "snap-none": "scroll-snap-type:none",
2575
+ "snap-x": "scroll-snap-type:x var(--tw-scroll-snap-strictness)",
2576
+ "snap-y": "scroll-snap-type:y var(--tw-scroll-snap-strictness)",
2577
+ "snap-mandatory": "--tw-scroll-snap-strictness:mandatory",
2578
+ "snap-proximity": "--tw-scroll-snap-strictness:proximity",
2579
+ "snap-align-none": "scroll-snap-align:none",
2580
+ "touch-none": "touch-action:none",
2581
+ "touch-auto": "touch-action:auto",
2582
+ "isolate": "isolation:isolate",
2583
+ "isolation-auto": "isolation:auto",
2584
+ "mix-blend-normal": "mix-blend-mode:normal",
2585
+ "mix-blend-multiply": "mix-blend-mode:multiply",
2586
+ "mix-blend-screen": "mix-blend-mode:screen",
2587
+ "mix-blend-overlay": "mix-blend-mode:overlay",
2588
+ "mix-blend-darken": "mix-blend-mode:darken",
2589
+ "mix-blend-lighten": "mix-blend-mode:lighten",
2590
+ "mix-blend-color-dodge": "mix-blend-mode:color-dodge",
2591
+ "mix-blend-color-burn": "mix-blend-mode:color-burn",
2592
+ "mix-blend-hard-light": "mix-blend-mode:hard-light",
2593
+ "mix-blend-soft-light": "mix-blend-mode:soft-light",
2594
+ "mix-blend-difference": "mix-blend-mode:difference",
2595
+ "mix-blend-exclusion": "mix-blend-mode:exclusion",
2596
+ "mix-blend-hue": "mix-blend-mode:hue",
2597
+ "mix-blend-saturation": "mix-blend-mode:saturation",
2598
+ "mix-blend-color": "mix-blend-mode:color",
2599
+ "mix-blend-luminosity": "mix-blend-mode:luminosity",
2600
+ "mix-blend-plus-lighter": "mix-blend-mode:plus-lighter",
2601
+ "underline-offset-0": "text-underline-offset:0px",
2602
+ "underline-offset-1": "text-underline-offset:1px",
2603
+ "underline-offset-2": "text-underline-offset:2px",
2604
+ "underline-offset-4": "text-underline-offset:4px",
2605
+ "underline-offset-8": "text-underline-offset:8px",
2606
+ "decoration-1": "text-decoration-thickness:1px",
2607
+ "decoration-2": "text-decoration-thickness:2px",
2608
+ "decoration-4": "text-decoration-thickness:4px",
2609
+ "decoration-8": "text-decoration-thickness:8px",
2610
+ "indent-px": "text-indent:1px",
2611
+ "columns-1": "columns:1",
2612
+ "columns-2": "columns:2",
2613
+ "columns-3": "columns:3",
2614
+ "columns-auto": "columns:auto",
2615
+ "w-0": "width:0",
2616
+ "w-1": "width:0.25rem",
2617
+ "w-2": "width:0.5rem",
2618
+ "w-3": "width:0.75rem",
2619
+ "w-4": "width:1rem",
2620
+ "w-6": "width:1.5rem",
2621
+ "w-8": "width:2rem",
2622
+ "w-10": "width:2.5rem",
2623
+ "w-12": "width:3rem",
2624
+ "w-14": "width:3.5rem",
2625
+ "w-16": "width:4rem",
2626
+ "w-20": "width:5rem",
2627
+ "w-24": "width:6rem",
2628
+ "w-28": "width:7rem",
2629
+ "w-32": "width:8rem",
2630
+ "w-36": "width:9rem",
2631
+ "w-40": "width:10rem",
2632
+ "w-44": "width:11rem",
2633
+ "w-48": "width:12rem",
2634
+ "w-52": "width:13rem",
2635
+ "w-56": "width:14rem",
2636
+ "w-60": "width:15rem",
2637
+ "w-64": "width:16rem",
2638
+ "w-72": "width:18rem",
2639
+ "w-80": "width:20rem",
2640
+ "w-96": "width:24rem",
2641
+ "h-0": "height:0",
2642
+ "h-1": "height:0.25rem",
2643
+ "h-2": "height:0.5rem",
2644
+ "h-3": "height:0.75rem",
2645
+ "h-4": "height:1rem",
2646
+ "h-6": "height:1.5rem",
2647
+ "h-8": "height:2rem",
2648
+ "h-10": "height:2.5rem",
2649
+ "h-12": "height:3rem",
2650
+ "h-14": "height:3.5rem",
2651
+ "h-16": "height:4rem",
2652
+ "h-20": "height:5rem",
2653
+ "h-24": "height:6rem",
2654
+ "h-28": "height:7rem",
2655
+ "h-32": "height:8rem",
2656
+ "h-36": "height:9rem",
2657
+ "h-40": "height:10rem",
2658
+ "h-44": "height:11rem",
2659
+ "h-48": "height:12rem",
2660
+ "h-52": "height:13rem",
2661
+ "h-56": "height:14rem",
2662
+ "h-60": "height:15rem",
2663
+ "h-64": "height:16rem",
2664
+ "h-72": "height:18rem",
2665
+ "h-80": "height:20rem",
2666
+ "h-96": "height:24rem",
2667
+ "min-w-0": "min-width:0",
2668
+ "min-w-1": "min-width:0.25rem",
2669
+ "min-w-2": "min-width:0.5rem",
2670
+ "min-w-3": "min-width:0.75rem",
2671
+ "min-w-4": "min-width:1rem",
2672
+ "min-w-6": "min-width:1.5rem",
2673
+ "min-w-8": "min-width:2rem",
2674
+ "min-w-10": "min-width:2.5rem",
2675
+ "min-w-12": "min-width:3rem",
2676
+ "min-w-14": "min-width:3.5rem",
2677
+ "min-w-16": "min-width:4rem",
2678
+ "min-w-20": "min-width:5rem",
2679
+ "min-w-24": "min-width:6rem",
2680
+ "min-w-28": "min-width:7rem",
2681
+ "min-w-32": "min-width:8rem",
2682
+ "min-w-36": "min-width:9rem",
2683
+ "min-w-40": "min-width:10rem",
2684
+ "min-w-44": "min-width:11rem",
2685
+ "min-w-48": "min-width:12rem",
2686
+ "min-w-52": "min-width:13rem",
2687
+ "min-w-56": "min-width:14rem",
2688
+ "min-w-60": "min-width:15rem",
2689
+ "min-w-64": "min-width:16rem",
2690
+ "min-w-72": "min-width:18rem",
2691
+ "min-w-80": "min-width:20rem",
2692
+ "min-w-96": "min-width:24rem",
2693
+ "max-w-xs": "max-width:20rem",
2694
+ "max-w-sm": "max-width:24rem",
2695
+ "max-w-md": "max-width:28rem",
2696
+ "max-w-lg": "max-width:32rem",
2697
+ "max-w-xl": "max-width:36rem",
2698
+ "max-w-2xl": "max-width:42rem",
2699
+ "max-w-3xl": "max-width:48rem",
2700
+ "max-w-4xl": "max-width:56rem",
2701
+ "max-w-5xl": "max-width:64rem",
2702
+ "max-w-6xl": "max-width:72rem",
2703
+ "max-w-7xl": "max-width:80rem",
2704
+ "max-w-prose": "max-width:65ch",
2705
+ "max-w-screen-sm": "max-width:40rem",
2706
+ "max-w-screen-md": "max-width:48rem",
2707
+ "max-w-screen-lg": "max-width:64rem",
2708
+ "max-w-screen-xl": "max-width:80rem",
2709
+ "max-w-screen-2xl": "max-width:96rem",
2710
+ "min-h-0": "min-height:0",
2711
+ "min-h-1": "min-height:0.25rem",
2712
+ "min-h-2": "min-height:0.5rem",
2713
+ "min-h-3": "min-height:0.75rem",
2714
+ "min-h-4": "min-height:1rem",
2715
+ "min-h-6": "min-height:1.5rem",
2716
+ "min-h-8": "min-height:2rem",
2717
+ "min-h-10": "min-height:2.5rem",
2718
+ "min-h-12": "min-height:3rem",
2719
+ "min-h-14": "min-height:3.5rem",
2720
+ "min-h-16": "min-height:4rem",
2721
+ "min-h-20": "min-height:5rem",
2722
+ "min-h-24": "min-height:6rem",
2723
+ "min-h-28": "min-height:7rem",
2724
+ "min-h-32": "min-height:8rem",
2725
+ "min-h-36": "min-height:9rem",
2726
+ "min-h-40": "min-height:10rem",
2727
+ "min-h-44": "min-height:11rem",
2728
+ "min-h-48": "min-height:12rem",
2729
+ "min-h-52": "min-height:13rem",
2730
+ "min-h-56": "min-height:14rem",
2731
+ "min-h-60": "min-height:15rem",
2732
+ "min-h-64": "min-height:16rem",
2733
+ "min-h-72": "min-height:18rem",
2734
+ "min-h-80": "min-height:20rem",
2735
+ "min-h-96": "min-height:24rem",
2736
+ "max-h-0": "max-height:0",
2737
+ "max-h-1": "max-height:0.25rem",
2738
+ "max-h-2": "max-height:0.5rem",
2739
+ "max-h-3": "max-height:0.75rem",
2740
+ "max-h-4": "max-height:1rem",
2741
+ "max-h-6": "max-height:1.5rem",
2742
+ "max-h-8": "max-height:2rem",
2743
+ "max-h-10": "max-height:2.5rem",
2744
+ "max-h-12": "max-height:3rem",
2745
+ "max-h-14": "max-height:3.5rem",
2746
+ "max-h-16": "max-height:4rem",
2747
+ "max-h-20": "max-height:5rem",
2748
+ "max-h-24": "max-height:6rem",
2749
+ "max-h-28": "max-height:7rem",
2750
+ "max-h-32": "max-height:8rem",
2751
+ "max-h-36": "max-height:9rem",
2752
+ "max-h-40": "max-height:10rem",
2753
+ "max-h-44": "max-height:11rem",
2754
+ "max-h-48": "max-height:12rem",
2755
+ "max-h-52": "max-height:13rem",
2756
+ "max-h-56": "max-height:14rem",
2757
+ "max-h-60": "max-height:15rem",
2758
+ "max-h-64": "max-height:16rem",
2759
+ "max-h-72": "max-height:18rem",
2760
+ "max-h-80": "max-height:20rem",
2761
+ "max-h-96": "max-height:24rem",
2762
+ "w-px": "width:1px",
2763
+ "h-px": "height:1px",
2764
+ "w-1/2": "width:50%",
2765
+ "w-1/3": "width:33.3333%",
2766
+ "w-1/4": "width:25%",
2767
+ "w-1/5": "width:20%",
2768
+ "w-1/6": "width:16.6667%",
2769
+ "w-2/3": "width:66.6667%",
2770
+ "w-2/4": "width:50%",
2771
+ "w-2/5": "width:40%",
2772
+ "w-2/6": "width:33.3333%",
2773
+ "w-3/4": "width:75%",
2774
+ "w-3/5": "width:60%",
2775
+ "w-3/6": "width:50%",
2776
+ "w-4/5": "width:80%",
2777
+ "w-4/6": "width:66.6667%",
2778
+ "w-5/6": "width:83.3333%",
2779
+ "h-1/2": "height:50%",
2780
+ "h-1/3": "height:33.3333%",
2781
+ "h-1/4": "height:25%",
2782
+ "h-1/5": "height:20%",
2783
+ "h-1/6": "height:16.6667%",
2784
+ "h-2/3": "height:66.6667%",
2785
+ "h-2/4": "height:50%",
2786
+ "h-2/5": "height:40%",
2787
+ "h-2/6": "height:33.3333%",
2788
+ "h-3/4": "height:75%",
2789
+ "h-3/5": "height:60%",
2790
+ "h-3/6": "height:50%",
2791
+ "h-4/5": "height:80%",
2792
+ "h-4/6": "height:66.6667%",
2793
+ "h-5/6": "height:83.3333%"
2794
+ };
2795
+ TW_VARIANTS_EXTRACTED = {
2796
+ "hover": ":hover",
2797
+ "focus": ":focus",
2798
+ "focus-visible": ":focus-visible",
2799
+ "active": ":active",
2800
+ "disabled": ":disabled",
2801
+ "group-hover": ":is(:where(.group):hover *)",
2802
+ "group-data": "[data-{attr}={value}]",
2803
+ "placeholder": "::placeholder",
2804
+ "before": "::before",
2805
+ "after": "::after",
2806
+ "file": "::file-selector-button",
2807
+ "marker": "::marker",
2808
+ "first-line": "::first-line",
2809
+ "first-letter": "::first-letter",
2810
+ "peer-checked": "inherited from base variant handling"
2811
+ };
2812
+ }
2813
+ });
2814
+
2815
+ // ../shared/src/mcp/tw-translate.ts
2816
+ function escapeClassName(cls) {
2817
+ return cls.replace(ESCAPE_RE, (c) => `\\${c}`).replace(/ /g, "\\ ");
2818
+ }
2819
+ function dataAriaVariant(v) {
2820
+ const m = v.match(/^(data|aria)-\[([^\]]+)\]$/);
2821
+ if (!m) return null;
2822
+ const [, kind, expr] = m;
2823
+ const eq = expr.match(/^([\w-]+)\s*=\s*(.+)$/);
2824
+ if (eq) {
2825
+ const val = eq[2].replace(/^["']|["']$/g, "");
2826
+ return (base) => `${base}[${kind}-${eq[1]}="${val}"]`;
2827
+ }
2828
+ return (base) => `${base}[${kind}-${expr}]`;
2829
+ }
2830
+ function applyVariant(selector, variant) {
2831
+ if (STATE_VARIANTS[variant]) return `${selector}${STATE_VARIANTS[variant]}`;
2832
+ if (PSEUDO_ELEMENTS[variant]) return `${selector}${PSEUDO_ELEMENTS[variant]}`;
2833
+ if (GROUP_PEER[variant]) return GROUP_PEER[variant](selector);
2834
+ if (TW_VARIANTS_EXTRACTED[variant] && !PSEUDO_ELEMENTS[variant] && !STATE_VARIANTS[variant]) {
2835
+ const suffix = TW_VARIANTS_EXTRACTED[variant];
2836
+ return suffix.startsWith(":") ? `${selector}${suffix}` : `${selector}${suffix}`;
2837
+ }
2838
+ const da = dataAriaVariant(variant);
2839
+ if (da) return da(selector);
2840
+ const ariaShort = variant.match(/^aria-(selected|checked|expanded|disabled|current|pressed|hidden)$/);
2841
+ if (ariaShort) return `${selector}[aria-${ariaShort[1]}="true"]`;
2842
+ const has = variant.match(/^has-\[(.+)\]$/);
2843
+ if (has) return `${selector}:has(${has[1].replace(/(?<!\\)_/g, " ")})`;
2844
+ const groupData = variant.match(/^group-(data|aria)-\[([^\]]+)\]$/);
2845
+ if (groupData) {
2846
+ const eq = groupData[2].match(/^([\w-]+)\s*=\s*(.+)$/);
2847
+ const attr = eq ? `${groupData[1]}-${eq[1]}="${eq[2].replace(/^["']|["']$/g, "")}"` : `${groupData[1]}-${groupData[2]}`;
2848
+ return `.group[${attr}] ${selector}`;
2849
+ }
2850
+ const groupArb = variant.match(/^group-\[(.+)\]$/);
2851
+ if (groupArb) {
2852
+ const inner = groupArb[1].replace(/&/g, "").replace(/(?<!\\)_/g, " ");
2853
+ return `.group${inner} ${selector}`;
2854
+ }
2855
+ const arb = variant.match(/^\[(.+)\]$/);
2856
+ if (arb && arb[1].includes("&")) {
2857
+ const inner = arb[1].replace(/&/g, selector).replace(/(?<!\\)_/g, " ");
2858
+ return inner;
2859
+ }
2860
+ return null;
2861
+ }
2862
+ function needsContent(variants, body) {
2863
+ return (variants.includes("before") || variants.includes("after")) && !/(^|;)\s*content\s*:/.test(body);
2864
+ }
2865
+ function spacing(token) {
2866
+ if (token === "px") return "1px";
2867
+ if (token === "full") return "100%";
2868
+ if (token === "auto") return "auto";
2869
+ if (token === "screen") return "100vh";
2870
+ if (/^\d+(\.\d+)?$/.test(token)) {
2871
+ const n = parseFloat(token);
2872
+ return `${(n * 0.25).toFixed(4).replace(/\.?0+$/, "")}rem`;
2873
+ }
2874
+ const frac = token.match(/^(\d+)\/(\d+)$/);
2875
+ if (frac) return `${(+frac[1] / +frac[2] * 100).toFixed(4).replace(/\.?0+$/, "")}%`;
2876
+ return null;
2877
+ }
2878
+ function colorValue(token) {
2879
+ const [name, op] = token.split("/");
2880
+ let base = null;
2881
+ if (name === "transparent") base = "transparent";
2882
+ else if (name === "current") base = "currentColor";
2883
+ else if (name === "white") base = "oklch(1 0 0)";
2884
+ else if (name === "black") base = "oklch(0 0 0)";
2885
+ else if (SEMANTIC_TOKENS.has(name)) base = `var(--${name})`;
2886
+ if (!base) return null;
2887
+ if (op && /^\d+$/.test(op)) {
2888
+ return `color-mix(in oklab, ${base} ${op}%, transparent)`;
2889
+ }
2890
+ return base;
2891
+ }
2892
+ function decodeArbitrary(raw) {
2893
+ const v = raw.replace(/(?<!\\)_/g, " ").replace(/\\_/g, "_").trim();
2894
+ return v && !/[{}<>;]/.test(v) ? v : null;
2895
+ }
2896
+ function animateModifier(base) {
2897
+ const spin = {
2898
+ "animate-spin": "animation:spin 1s linear infinite",
2899
+ "animate-pulse": "animation:pulse 2s cubic-bezier(0.4,0,0.6,1) infinite",
2900
+ "animate-bounce": "animation:bounce 1s infinite",
2901
+ "animate-ping": "animation:ping 1s cubic-bezier(0,0,0.2,1) infinite",
2902
+ "animate-accordion-down": "animation:accordion-down 0.2s ease-out",
2903
+ "animate-accordion-up": "animation:accordion-up 0.2s ease-out",
2904
+ "animate-collapsible-down": "animation:collapsible-down 0.2s ease-out",
2905
+ "animate-collapsible-up": "animation:collapsible-up 0.2s ease-out",
2906
+ "animate-none": "animation:none"
2907
+ };
2908
+ if (spin[base]) return spin[base];
2909
+ let m = base.match(/^(fade|zoom)-(in|out)-(\d+)$/);
2910
+ if (m) {
2911
+ const kind = m[2] === "in" ? "enter" : "exit";
2912
+ if (m[1] === "fade") return `--tw-${kind}-opacity:${(+m[3] / 100).toString().replace(/^0\./, ".")}`;
2913
+ return `--tw-${kind}-scale:${(+m[3] / 100).toString().replace(/^0\./, ".")}`;
2914
+ }
2915
+ m = base.match(/^slide-(in-from|out-to)-(top|bottom|left|right)-(.+)$/);
2916
+ if (m) {
2917
+ const kind = m[1] === "in-from" ? "enter" : "exit";
2918
+ const axis = m[2] === "top" || m[2] === "bottom" ? "y" : "x";
2919
+ const sign = m[2] === "top" || m[2] === "left" ? "-" : "";
2920
+ const v = m[3].startsWith("[") ? decodeArbitrary(m[3].slice(1, -1)) : spacing(m[3]);
2921
+ if (v) return `--tw-${kind}-translate-${axis}:${sign}${v}`;
2922
+ }
2923
+ return null;
2924
+ }
2925
+ function paletteColor(base) {
2926
+ const m = base.match(/^([a-z]+(?:-[trbl])?)-([a-z]+)-(\d{2,3})(?:\/(\d+))?$/);
2927
+ if (!m) return null;
2928
+ const prop = COLOR_PROP[m[1]];
2929
+ const shade = PALETTE[m[2]]?.[m[3]];
2930
+ if (!prop || !shade) return null;
2931
+ const val = m[4] ? `color-mix(in oklab, ${shade} ${m[4]}%, transparent)` : shade;
2932
+ return `${prop}:${val}`;
2933
+ }
2934
+ function translateBase(base) {
2935
+ if (TW_STATIC_EXTRACTED[base]) return TW_STATIC_EXTRACTED[base];
2936
+ if (STATIC[base]) return STATIC[base];
2937
+ if (KNOWN_EMPTY.has(base)) return "";
2938
+ if (FONT_FAMILY[base]) return FONT_FAMILY[base];
2939
+ if (FLEX_EXTRA[base]) return FLEX_EXTRA[base];
2940
+ const anim = animateModifier(base);
2941
+ if (anim) return anim;
2942
+ const pal = paletteColor(base);
2943
+ if (pal) return pal;
2944
+ if (FONT_SIZE[base]) return FONT_SIZE[base];
2945
+ if (FONT_WEIGHT[base]) return `font-weight:${FONT_WEIGHT[base]}`;
2946
+ if (RADIUS[base]) return `border-radius:${RADIUS[base]}`;
2947
+ const propArb = base.match(/^\[([\w-]+):(.+)\]$/);
2948
+ if (propArb) {
2949
+ const val = decodeArbitrary(propArb[2]);
2950
+ return val ? `${propArb[1]}:${val}` : null;
2951
+ }
2952
+ const rsa = base.match(/^rounded-(t|r|b|l|tl|tr|br|bl)-\[(.+)\]$/);
2953
+ if (rsa && RADIUS_SIDE[rsa[1]]) {
2954
+ const v = decodeArbitrary(rsa[2]);
2955
+ if (v) return RADIUS_SIDE[rsa[1]].map((p) => `${p}:${v}`).join(";");
2956
+ }
2957
+ const arb = base.match(/^(-?[a-z][\w-]*)-\[(.+)\](?:\/(\d+))?$/);
2958
+ if (arb) {
2959
+ const val = decodeArbitrary(arb[2]);
2960
+ if (val) {
2961
+ const prop = ARBITRARY_PROP[arb[1]];
2962
+ if (prop) return `${prop}:${val}`;
2963
+ const colorProp = COLOR_PROP[arb[1]];
2964
+ if (colorProp) {
2965
+ const v = arb[3] ? `color-mix(in oklab, ${val} ${arb[3]}%, transparent)` : val;
2966
+ return `${colorProp}:${v}`;
2967
+ }
2968
+ }
2969
+ }
2970
+ const rside = base.match(/^rounded-(t|r|b|l|tl|tr|br|bl)(?:-(.+))?$/);
2971
+ if (rside_ok(rside)) {
2972
+ const props = RADIUS_SIDE[rside[1]];
2973
+ const key = rside[2] ? `rounded-${rside[2]}` : "rounded";
2974
+ const val = RADIUS[key];
2975
+ if (val) return props.map((p) => `${p}:${val}`).join(";");
2976
+ }
2977
+ const colorMatch = base.match(/^([a-z]+(?:-[trbl])?)-(.+)$/);
2978
+ if (colorMatch && COLOR_PROP[colorMatch[1]]) {
2979
+ const val = colorValue(colorMatch[2]);
2980
+ if (val) return `${COLOR_PROP[colorMatch[1]]}:${val}`;
2981
+ }
2982
+ const sp = base.match(/^(-)?([a-z]+(?:-[xytrbl])?)-(.+)$/);
2983
+ if (sp && SPACING_PROP[sp[2]]) {
2984
+ const v = spacing(sp[3]);
2985
+ if (v) {
2986
+ const val = sp[1] ? `-${v}` : v;
2987
+ return SPACING_PROP[sp[2]].map((p) => `${p}:${val}`).join(";");
2988
+ }
2989
+ }
2990
+ const sz = base.match(/^(w|h|min-w|max-w|min-h|max-h|size)-(.+)$/);
2991
+ if (sz && SIZE_PROP[sz[1]]) {
2992
+ const v = sz[2] === "max" ? "max-content" : sz[2] === "min" ? "min-content" : sz[2] === "fit" ? "fit-content" : MAX_W_SCALE[sz[2]] ?? spacing(sz[2]);
2993
+ if (v) return SIZE_PROP[sz[1]].map((p) => `${p}:${v}`).join(";");
2994
+ }
2995
+ const tr = base.match(/^(-)?translate-([xy])-(.+)$/);
2996
+ if (tr) {
2997
+ const raw = tr[3].startsWith("[") ? decodeArbitrary(tr[3].slice(1, -1)) : spacing(tr[3]);
2998
+ if (raw) {
2999
+ const v = `${tr[1] ?? ""}${raw}`;
3000
+ return `--tw-translate-${tr[2]}:${v};translate:var(--tw-translate-x) var(--tw-translate-y)`;
3001
+ }
3002
+ }
3003
+ const nz = base.match(/^-z-(\d+)$/);
3004
+ if (nz) return `z-index:-${nz[1]}`;
3005
+ const bw = base.match(/^border-([trbl])-(\d+)$/);
3006
+ if (bw) {
3007
+ const side = { t: "top", r: "right", b: "bottom", l: "left" }[bw[1]];
3008
+ return `border-${side}-width:${bw[2]}px`;
3009
+ }
3010
+ const lh = base.match(/^leading-(\d+)$/);
3011
+ if (lh) return `line-height:${(+lh[1] * 0.25).toString().replace(/\.?0+$/, "")}rem`;
3012
+ const fil = base.match(/^(backdrop-)?(brightness|saturate|contrast|grayscale|invert|sepia|blur)-(\d+|none)$/);
3013
+ if (fil) {
3014
+ const prop = fil[1] ? "backdrop-filter" : "filter";
3015
+ const fn = fil[2];
3016
+ const n = fil[3] === "none" ? fn === "blur" ? "0" : "100" : fil[3];
3017
+ const arg = fn === "blur" ? `${n}px` : ["grayscale", "invert", "sepia"].includes(fn) ? `${+n / 100}` : `${n}%`;
3018
+ return `${prop}:${fn}(${arg})`;
3019
+ }
3020
+ const sm = base.match(/^scroll-(m|mt|mr|mb|ml|p|pt|pr|pb|pl)([xy])?-(.+)$/);
3021
+ if (sm) {
3022
+ const v = spacing(sm[3]);
3023
+ if (v) {
3024
+ const kind = sm[1][0] === "m" ? "margin" : "padding";
3025
+ const side = { t: "-top", r: "-right", b: "-bottom", l: "-left", x: "-inline", y: "-block" }[sm[1][1] ?? sm[2] ?? ""] ?? "";
3026
+ return `scroll-${kind}${side}:${v}`;
3027
+ }
3028
+ }
3029
+ return null;
3030
+ }
3031
+ function rside_ok(m) {
3032
+ return !!m && !!RADIUS_SIDE[m[1]];
3033
+ }
3034
+ function translateClass(cls) {
3035
+ if (!cls || cls.startsWith("//")) return null;
3036
+ const parts = splitVariants(cls);
3037
+ const base = parts.pop();
3038
+ let body = translateBase(base);
3039
+ if (body === null) return null;
3040
+ if (needsContent(parts, body)) body = `content:"";${body}`;
3041
+ let selector = `.${escapeClassName(cls)}`;
3042
+ let media;
3043
+ for (const v of parts) {
3044
+ if (BREAKPOINTS[v]) {
3045
+ media = `(min-width:${BREAKPOINTS[v]})`;
3046
+ continue;
3047
+ }
3048
+ const next = applyVariant(selector, v);
3049
+ if (!next) return null;
3050
+ selector = next;
3051
+ }
3052
+ return { selector, body, media };
3053
+ }
3054
+ function splitVariants(cls) {
3055
+ const out = [];
3056
+ let depth = 0;
3057
+ let cur = "";
3058
+ for (const ch of cls) {
3059
+ if (ch === "[") depth++;
3060
+ else if (ch === "]") depth--;
3061
+ if (ch === ":" && depth === 0) {
3062
+ out.push(cur);
3063
+ cur = "";
3064
+ } else cur += ch;
3065
+ }
3066
+ out.push(cur);
3067
+ return out;
3068
+ }
3069
+ var BREAKPOINTS, KNOWN_EMPTY, PALETTE, FONT_FAMILY, FLEX_EXTRA, TW_DEFAULTS, ESCAPE_RE, STATE_VARIANTS, GROUP_PEER, PSEUDO_ELEMENTS, SPACING_PROP, SIZE_PROP, COLOR_PROP, SEMANTIC_TOKENS, RADIUS, RADIUS_SIDE, FONT_SIZE, FONT_WEIGHT, STATIC, ARBITRARY_PROP, MAX_W_SCALE;
3070
+ var init_tw_translate = __esm({
3071
+ "../shared/src/mcp/tw-translate.ts"() {
3072
+ "use strict";
3073
+ init_tw_extracted_generated();
3074
+ BREAKPOINTS = {
3075
+ sm: "40rem",
3076
+ md: "48rem",
3077
+ lg: "64rem",
3078
+ xl: "80rem",
3079
+ "2xl": "96rem"
3080
+ };
3081
+ KNOWN_EMPTY = /* @__PURE__ */ new Set(["group", "peer"]);
3082
+ PALETTE = {
3083
+ emerald: { "50": "oklch(0.979 0.021 166.1)", "100": "oklch(0.95 0.052 163.1)", "200": "oklch(0.905 0.093 164.2)", "400": "oklch(0.765 0.177 163.2)", "500": "oklch(0.696 0.17 162.5)", "600": "oklch(0.596 0.145 163.2)", "700": "oklch(0.508 0.118 165.6)" },
3084
+ green: { "50": "oklch(0.982 0.018 155.8)", "100": "oklch(0.962 0.044 156.7)", "400": "oklch(0.792 0.209 151.7)", "500": "oklch(0.723 0.219 149.6)", "600": "oklch(0.627 0.194 149.2)", "700": "oklch(0.527 0.154 150.1)" },
3085
+ orange: { "50": "oklch(0.98 0.016 73.7)", "100": "oklch(0.954 0.038 75.2)", "200": "oklch(0.901 0.076 70.7)", "400": "oklch(0.75 0.183 55.9)", "500": "oklch(0.705 0.213 47.6)", "600": "oklch(0.646 0.222 41.1)", "700": "oklch(0.553 0.195 38.4)" },
3086
+ amber: { "50": "oklch(0.987 0.022 95.3)", "100": "oklch(0.962 0.059 95.6)", "400": "oklch(0.828 0.189 84.4)", "500": "oklch(0.769 0.188 70.1)", "600": "oklch(0.666 0.179 58.3)", "700": "oklch(0.555 0.163 48.998)" },
3087
+ red: { "50": "oklch(0.971 0.013 17.4)", "100": "oklch(0.936 0.032 17.7)", "200": "oklch(0.885 0.062 18.3)", "300": "oklch(0.808 0.114 19.6)", "400": "oklch(0.704 0.191 22.2)", "500": "oklch(0.637 0.237 25.3)", "600": "oklch(0.577 0.245 27.3)", "700": "oklch(0.505 0.213 27.5)" },
3088
+ yellow: { "50": "oklch(0.987 0.026 102.2)", "100": "oklch(0.973 0.071 103.2)", "400": "oklch(0.852 0.199 91.9)", "500": "oklch(0.795 0.184 86.05)", "600": "oklch(0.681 0.162 75.8)", "700": "oklch(0.554 0.135 66.4)" },
3089
+ blue: { "50": "oklch(0.97 0.014 254.6)", "100": "oklch(0.932 0.032 255.6)", "500": "oklch(0.623 0.214 259.8)", "600": "oklch(0.546 0.245 262.9)", "700": "oklch(0.488 0.243 264.4)" },
3090
+ sky: { "50": "oklch(0.977 0.013 236.6)", "100": "oklch(0.951 0.026 236.8)", "500": "oklch(0.685 0.169 237.3)", "600": "oklch(0.588 0.158 241.97)", "700": "oklch(0.5 0.134 242.7)" },
3091
+ rose: { "50": "oklch(0.969 0.015 12.4)", "100": "oklch(0.941 0.03 12.6)", "500": "oklch(0.645 0.246 16.4)", "600": "oklch(0.586 0.253 17.6)", "700": "oklch(0.514 0.222 16.9)" },
3092
+ slate: { "50": "oklch(0.984 0.003 247.9)", "100": "oklch(0.968 0.007 247.9)", "500": "oklch(0.554 0.046 257.4)", "600": "oklch(0.446 0.043 257.3)", "700": "oklch(0.372 0.044 257.3)", "900": "oklch(0.208 0.042 265.8)" },
3093
+ zinc: { "50": "oklch(0.985 0 0)", "100": "oklch(0.967 0.001 286.4)", "400": "oklch(0.705 0.015 286.1)", "500": "oklch(0.552 0.016 285.9)", "600": "oklch(0.442 0.017 285.8)", "700": "oklch(0.37 0.013 285.8)", "800": "oklch(0.274 0.006 286)", "900": "oklch(0.21 0.006 285.9)" },
3094
+ gray: { "50": "oklch(0.985 0.002 247.8)", "100": "oklch(0.967 0.003 264.5)", "400": "oklch(0.707 0.022 261.3)", "500": "oklch(0.551 0.027 264.4)", "600": "oklch(0.446 0.03 256.8)", "700": "oklch(0.373 0.034 259.7)", "900": "oklch(0.21 0.034 264.7)" },
3095
+ neutral: { "50": "oklch(0.985 0 0)", "100": "oklch(0.97 0 0)", "400": "oklch(0.708 0 0)", "500": "oklch(0.556 0 0)", "600": "oklch(0.439 0 0)", "700": "oklch(0.371 0 0)", "900": "oklch(0.205 0 0)" }
3096
+ };
3097
+ FONT_FAMILY = {
3098
+ "font-sans": "font-family:var(--font-sans)",
3099
+ "font-serif": "font-family:var(--font-serif)",
3100
+ "font-mono": "font-family:var(--font-mono)"
3101
+ };
3102
+ FLEX_EXTRA = {
3103
+ "flex-col-reverse": "flex-direction:column-reverse",
3104
+ "flex-wrap-reverse": "flex-wrap:wrap-reverse",
3105
+ "caption-bottom": "caption-side:bottom",
3106
+ "shrink": "flex-shrink:1",
3107
+ "sr-only": "position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0"
3108
+ };
3109
+ TW_DEFAULTS = "*,::before,::after,::backdrop{--tw-ring-color:currentcolor;--tw-ring-shadow:0 0 0 transparent;--tw-ring-offset-shadow:0 0 0 transparent;--tw-ring-offset-width:0px;--tw-ring-offset-color:oklch(1 0 0);--tw-ring-inset:;--tw-shadow:0 0 0 transparent;--tw-inset-shadow:0 0 0 transparent;--tw-inset-ring-shadow:0 0 0 transparent;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:;--tw-rotate-y:;--tw-rotate-z:;--tw-skew-x:;--tw-skew-y:;--tw-gradient-from:transparent;--tw-gradient-to:transparent;--tw-gradient-stops:;--tw-blur:;--tw-brightness:;--tw-contrast:;--tw-saturate:;--tw-content:''}";
3110
+ ESCAPE_RE = /[:\\[\]/.#(),%!&>~*+="'@]/g;
3111
+ STATE_VARIANTS = {
3112
+ hover: ":hover",
3113
+ focus: ":focus",
3114
+ "focus-visible": ":focus-visible",
3115
+ "focus-within": ":focus-within",
3116
+ active: ":active",
3117
+ visited: ":visited",
3118
+ disabled: ":disabled",
3119
+ checked: ":checked",
3120
+ required: ":required",
3121
+ "read-only": ":read-only",
3122
+ "first": ":first-child",
3123
+ "last": ":last-child",
3124
+ "odd": ":nth-child(odd)",
3125
+ "even": ":nth-child(even)",
3126
+ "empty": ":empty"
3127
+ };
3128
+ GROUP_PEER = {
3129
+ "group-hover": (s) => `.group:hover ${s}`,
3130
+ "group-focus": (s) => `.group:focus ${s}`,
3131
+ "peer-hover": (s) => `.peer:hover ~ ${s}`,
3132
+ "peer-focus": (s) => `.peer:focus ~ ${s}`,
3133
+ "peer-checked": (s) => `.peer:checked ~ ${s}`,
3134
+ "peer-disabled": (s) => `.peer:disabled ~ ${s}`
3135
+ };
3136
+ PSEUDO_ELEMENTS = {
3137
+ placeholder: "::placeholder",
3138
+ before: "::before",
3139
+ after: "::after",
3140
+ file: "::file-selector-button",
3141
+ marker: "::marker",
3142
+ selection: "::selection",
3143
+ "first-line": "::first-line",
3144
+ "first-letter": "::first-letter",
3145
+ backdrop: "::backdrop"
3146
+ };
3147
+ SPACING_PROP = {
3148
+ p: ["padding"],
3149
+ px: ["padding-left", "padding-right"],
3150
+ py: ["padding-top", "padding-bottom"],
3151
+ pt: ["padding-top"],
3152
+ pr: ["padding-right"],
3153
+ pb: ["padding-bottom"],
3154
+ pl: ["padding-left"],
3155
+ ps: ["padding-inline-start"],
3156
+ pe: ["padding-inline-end"],
3157
+ m: ["margin"],
3158
+ mx: ["margin-left", "margin-right"],
3159
+ my: ["margin-top", "margin-bottom"],
3160
+ mt: ["margin-top"],
3161
+ mr: ["margin-right"],
3162
+ mb: ["margin-bottom"],
3163
+ ml: ["margin-left"],
3164
+ ms: ["margin-inline-start"],
3165
+ me: ["margin-inline-end"],
3166
+ gap: ["gap"],
3167
+ "gap-x": ["column-gap"],
3168
+ "gap-y": ["row-gap"],
3169
+ "space-x": ["column-gap"],
3170
+ "space-y": ["row-gap"],
3171
+ // approximation
3172
+ inset: ["inset"],
3173
+ top: ["top"],
3174
+ right: ["right"],
3175
+ bottom: ["bottom"],
3176
+ left: ["left"]
3177
+ };
3178
+ SIZE_PROP = {
3179
+ w: ["width"],
3180
+ "min-w": ["min-width"],
3181
+ "max-w": ["max-width"],
3182
+ h: ["height"],
3183
+ "min-h": ["min-height"],
3184
+ "max-h": ["max-height"],
3185
+ size: ["width", "height"]
3186
+ };
3187
+ COLOR_PROP = {
3188
+ bg: "background-color",
3189
+ text: "color",
3190
+ border: "border-color",
3191
+ "border-t": "border-top-color",
3192
+ "border-r": "border-right-color",
3193
+ "border-b": "border-bottom-color",
3194
+ "border-l": "border-left-color",
3195
+ ring: "--tw-ring-color",
3196
+ fill: "fill",
3197
+ stroke: "stroke",
3198
+ outline: "outline-color",
3199
+ decoration: "text-decoration-color",
3200
+ caret: "caret-color",
3201
+ accent: "accent-color",
3202
+ from: "--tw-gradient-from",
3203
+ to: "--tw-gradient-to",
3204
+ via: "--tw-gradient-via"
3205
+ };
3206
+ SEMANTIC_TOKENS = /* @__PURE__ */ new Set([
3207
+ "background",
3208
+ "foreground",
3209
+ "card",
3210
+ "card-foreground",
3211
+ "popover",
3212
+ "popover-foreground",
3213
+ "primary",
3214
+ "primary-foreground",
3215
+ "secondary",
3216
+ "secondary-foreground",
3217
+ "muted",
3218
+ "muted-foreground",
3219
+ "accent",
3220
+ "accent-foreground",
3221
+ "destructive",
3222
+ "destructive-foreground",
3223
+ "border",
3224
+ "input",
3225
+ "ring",
3226
+ "chart-1",
3227
+ "chart-2",
3228
+ "chart-3",
3229
+ "chart-4",
3230
+ "chart-5",
3231
+ "sidebar",
3232
+ "sidebar-foreground",
3233
+ "sidebar-primary",
3234
+ "sidebar-accent",
3235
+ "sidebar-border"
3236
+ ]);
3237
+ RADIUS = {
3238
+ "rounded-none": "0",
3239
+ "rounded-sm": "var(--radius-sm, calc(var(--radius) - 4px))",
3240
+ "rounded": "0.25rem",
3241
+ "rounded-md": "var(--radius-md, calc(var(--radius) - 2px))",
3242
+ "rounded-lg": "var(--radius-lg, var(--radius))",
3243
+ "rounded-xl": "var(--radius-xl, calc(var(--radius) + 4px))",
3244
+ "rounded-2xl": "var(--radius-2xl, 1rem)",
3245
+ "rounded-3xl": "var(--radius-3xl, 1.5rem)",
3246
+ "rounded-full": "calc(infinity * 1px)"
3247
+ };
3248
+ RADIUS_SIDE = {
3249
+ t: ["border-top-left-radius", "border-top-right-radius"],
3250
+ r: ["border-top-right-radius", "border-bottom-right-radius"],
3251
+ b: ["border-bottom-left-radius", "border-bottom-right-radius"],
3252
+ l: ["border-top-left-radius", "border-bottom-left-radius"],
3253
+ tl: ["border-top-left-radius"],
3254
+ tr: ["border-top-right-radius"],
3255
+ br: ["border-bottom-right-radius"],
3256
+ bl: ["border-bottom-left-radius"]
3257
+ };
3258
+ FONT_SIZE = {
3259
+ "text-xs": "font-size:0.75rem;line-height:1rem",
3260
+ "text-sm": "font-size:0.875rem;line-height:1.25rem",
3261
+ "text-base": "font-size:1rem;line-height:1.5rem",
3262
+ "text-lg": "font-size:1.125rem;line-height:1.75rem",
3263
+ "text-xl": "font-size:1.25rem;line-height:1.75rem",
3264
+ "text-2xl": "font-size:1.5rem;line-height:2rem",
3265
+ "text-3xl": "font-size:1.875rem;line-height:2.25rem",
3266
+ "text-4xl": "font-size:2.25rem;line-height:2.5rem",
3267
+ "text-5xl": "font-size:3rem;line-height:1",
3268
+ "text-6xl": "font-size:3.75rem;line-height:1"
3269
+ };
3270
+ FONT_WEIGHT = {
3271
+ "font-thin": "100",
3272
+ "font-extralight": "200",
3273
+ "font-light": "300",
3274
+ "font-normal": "400",
3275
+ "font-medium": "500",
3276
+ "font-semibold": "600",
3277
+ "font-bold": "700",
3278
+ "font-extrabold": "800",
3279
+ "font-black": "900"
3280
+ };
3281
+ STATIC = {
3282
+ // display / box
3283
+ block: "display:block",
3284
+ "inline-block": "display:inline-block",
3285
+ inline: "display:inline",
3286
+ flex: "display:flex",
3287
+ "inline-flex": "display:inline-flex",
3288
+ grid: "display:grid",
3289
+ "inline-grid": "display:inline-grid",
3290
+ hidden: "display:none",
3291
+ contents: "display:contents",
3292
+ invisible: "visibility:hidden",
3293
+ visible: "visibility:visible",
3294
+ "sr-only-x": "",
3295
+ table: "display:table",
3296
+ "table-cell": "display:table-cell",
3297
+ "table-row": "display:table-row",
3298
+ // flex / grid
3299
+ "flex-row": "flex-direction:row",
3300
+ "flex-col": "flex-direction:column",
3301
+ "flex-row-reverse": "flex-direction:row-reverse",
3302
+ "flex-wrap": "flex-wrap:wrap",
3303
+ "flex-nowrap": "flex-wrap:nowrap",
3304
+ "flex-1": "flex:1 1 0%",
3305
+ "flex-auto": "flex:1 1 auto",
3306
+ "flex-initial": "flex:0 1 auto",
3307
+ "flex-none": "flex:none",
3308
+ "flex-shrink-0": "flex-shrink:0",
3309
+ "shrink-0": "flex-shrink:0",
3310
+ grow: "flex-grow:1",
3311
+ "grow-0": "flex-grow:0",
3312
+ "items-center": "align-items:center",
3313
+ "items-start": "align-items:flex-start",
3314
+ "items-end": "align-items:flex-end",
3315
+ "items-stretch": "align-items:stretch",
3316
+ "items-baseline": "align-items:baseline",
3317
+ "justify-center": "justify-content:center",
3318
+ "justify-start": "justify-content:flex-start",
3319
+ "justify-end": "justify-content:flex-end",
3320
+ "justify-between": "justify-content:space-between",
3321
+ "justify-around": "justify-content:space-around",
3322
+ "justify-evenly": "justify-content:space-evenly",
3323
+ "self-center": "align-self:center",
3324
+ "self-start": "align-self:flex-start",
3325
+ "self-end": "align-self:flex-end",
3326
+ "self-stretch": "align-self:stretch",
3327
+ "content-center": "align-content:center",
3328
+ "place-items-center": "place-items:center",
3329
+ "place-content-center": "place-content:center",
3330
+ // position
3331
+ relative: "position:relative",
3332
+ absolute: "position:absolute",
3333
+ fixed: "position:fixed",
3334
+ sticky: "position:sticky",
3335
+ static: "position:static",
3336
+ "inset-0": "inset:0",
3337
+ "inset-x-0": "left:0;right:0",
3338
+ "inset-y-0": "top:0;bottom:0",
3339
+ // sizing shorthands
3340
+ "w-full": "width:100%",
3341
+ "h-full": "height:100%",
3342
+ "w-screen": "width:100vw",
3343
+ "h-screen": "height:100vh",
3344
+ "min-h-screen": "min-height:100vh",
3345
+ "w-fit": "width:fit-content",
3346
+ "h-fit": "height:fit-content",
3347
+ "w-auto": "width:auto",
3348
+ "h-auto": "height:auto",
3349
+ "min-w-0": "min-width:0",
3350
+ "max-w-full": "max-width:100%",
3351
+ "min-h-0": "min-height:0",
3352
+ "size-full": "width:100%;height:100%",
3353
+ // overflow / misc
3354
+ "overflow-hidden": "overflow:hidden",
3355
+ "overflow-auto": "overflow:auto",
3356
+ "overflow-x-auto": "overflow-x:auto",
3357
+ "overflow-y-auto": "overflow-y:auto",
3358
+ "overflow-visible": "overflow:visible",
3359
+ "overflow-x-hidden": "overflow-x:hidden",
3360
+ "overflow-y-hidden": "overflow-y:hidden",
3361
+ truncate: "overflow:hidden;text-overflow:ellipsis;white-space:nowrap",
3362
+ "whitespace-nowrap": "white-space:nowrap",
3363
+ "whitespace-pre": "white-space:pre",
3364
+ "break-words": "overflow-wrap:break-word",
3365
+ "break-all": "word-break:break-all",
3366
+ "select-none": "user-select:none",
3367
+ "select-text": "user-select:text",
3368
+ "pointer-events-none": "pointer-events:none",
3369
+ "pointer-events-auto": "pointer-events:auto",
3370
+ "cursor-pointer": "cursor:pointer",
3371
+ "cursor-default": "cursor:default",
3372
+ "cursor-not-allowed": "cursor:not-allowed",
3373
+ "cursor-text": "cursor:text",
3374
+ // typography
3375
+ "text-left": "text-align:left",
3376
+ "text-center": "text-align:center",
3377
+ "text-right": "text-align:right",
3378
+ "text-justify": "text-align:justify",
3379
+ italic: "font-style:italic",
3380
+ "not-italic": "font-style:normal",
3381
+ underline: "text-decoration-line:underline",
3382
+ "line-through": "text-decoration-line:line-through",
3383
+ "no-underline": "text-decoration-line:none",
3384
+ uppercase: "text-transform:uppercase",
3385
+ lowercase: "text-transform:lowercase",
3386
+ capitalize: "text-transform:capitalize",
3387
+ "normal-case": "text-transform:none",
3388
+ "leading-none": "line-height:1",
3389
+ "leading-tight": "line-height:1.25",
3390
+ "leading-snug": "line-height:1.375",
3391
+ "leading-normal": "line-height:1.5",
3392
+ "leading-relaxed": "line-height:1.625",
3393
+ "leading-loose": "line-height:2",
3394
+ "tracking-tighter": "letter-spacing:-0.05em",
3395
+ "tracking-tight": "letter-spacing:-0.025em",
3396
+ "tracking-normal": "letter-spacing:0",
3397
+ "tracking-wide": "letter-spacing:0.025em",
3398
+ "tracking-wider": "letter-spacing:0.05em",
3399
+ "tracking-widest": "letter-spacing:0.1em",
3400
+ "tabular-nums": "font-variant-numeric:tabular-nums",
3401
+ "antialiased": "-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale",
3402
+ // borders
3403
+ border: "border-width:1px",
3404
+ "border-0": "border-width:0",
3405
+ "border-2": "border-width:2px",
3406
+ "border-t": "border-top-width:1px",
3407
+ "border-r": "border-right-width:1px",
3408
+ "border-b": "border-bottom-width:1px",
3409
+ "border-l": "border-left-width:1px",
3410
+ "border-solid": "border-style:solid",
3411
+ "border-dashed": "border-style:dashed",
3412
+ "border-none": "border-style:none",
3413
+ // effects
3414
+ "shadow-none": "box-shadow:none",
3415
+ "shadow-xs": "box-shadow:var(--shadow-xs, 0 1px 2px 0 oklch(0 0 0 / 0.05))",
3416
+ "shadow-sm": "box-shadow:var(--shadow-sm, 0 1px 3px 0 oklch(0 0 0 / 0.1))",
3417
+ shadow: "box-shadow:var(--shadow, 0 1px 3px 0 oklch(0 0 0 / 0.1))",
3418
+ "shadow-md": "box-shadow:var(--shadow-md, 0 4px 6px -1px oklch(0 0 0 / 0.1))",
3419
+ "shadow-lg": "box-shadow:var(--shadow-lg, 0 10px 15px -3px oklch(0 0 0 / 0.1))",
3420
+ "shadow-xl": "box-shadow:var(--shadow-xl, 0 20px 25px -5px oklch(0 0 0 / 0.1))",
3421
+ "shadow-2xl": "box-shadow:var(--shadow-2xl, 0 25px 50px -12px oklch(0 0 0 / 0.25))",
3422
+ "opacity-0": "opacity:0",
3423
+ "opacity-50": "opacity:0.5",
3424
+ "opacity-100": "opacity:1",
3425
+ "ring-0": "box-shadow:0 0 0 0",
3426
+ "outline-none": "outline:2px solid transparent;outline-offset:2px",
3427
+ // transitions
3428
+ "transition-none": "transition-property:none",
3429
+ transition: "transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(0.4,0,0.2,1);transition-duration:150ms",
3430
+ "transition-colors": "transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(0.4,0,0.2,1);transition-duration:150ms",
3431
+ "transition-transform": "transition-property:transform;transition-timing-function:cubic-bezier(0.4,0,0.2,1);transition-duration:150ms",
3432
+ "transition-opacity": "transition-property:opacity;transition-timing-function:cubic-bezier(0.4,0,0.2,1);transition-duration:150ms",
3433
+ "transition-shadow": "transition-property:box-shadow;transition-timing-function:cubic-bezier(0.4,0,0.2,1);transition-duration:150ms",
3434
+ "duration-75": "transition-duration:75ms",
3435
+ "duration-100": "transition-duration:100ms",
3436
+ "duration-150": "transition-duration:150ms",
3437
+ "duration-200": "transition-duration:200ms",
3438
+ "duration-300": "transition-duration:300ms",
3439
+ "duration-500": "transition-duration:500ms",
3440
+ "ease-linear": "transition-timing-function:linear",
3441
+ "ease-in": "transition-timing-function:cubic-bezier(0.4,0,1,1)",
3442
+ "ease-out": "transition-timing-function:cubic-bezier(0,0,0.2,1)",
3443
+ "ease-in-out": "transition-timing-function:cubic-bezier(0.4,0,0.2,1)",
3444
+ // z-index
3445
+ "z-0": "z-index:0",
3446
+ "z-10": "z-index:10",
3447
+ "z-20": "z-index:20",
3448
+ "z-30": "z-index:30",
3449
+ "z-40": "z-index:40",
3450
+ "z-50": "z-index:50",
3451
+ "z-auto": "z-index:auto",
3452
+ // transform-origin
3453
+ "origin-center": "transform-origin:center",
3454
+ "origin-top": "transform-origin:top",
3455
+ "origin-bottom": "transform-origin:bottom",
3456
+ "origin-left": "transform-origin:left",
3457
+ "origin-right": "transform-origin:right",
3458
+ "origin-top-left": "transform-origin:top left",
3459
+ "origin-top-right": "transform-origin:top right",
3460
+ "origin-bottom-left": "transform-origin:bottom left",
3461
+ "origin-bottom-right": "transform-origin:bottom right",
3462
+ "origin-top-center": "transform-origin:top center",
3463
+ // table / misc
3464
+ "border-collapse": "border-collapse:collapse",
3465
+ "border-separate": "border-collapse:separate",
3466
+ "table-auto": "table-layout:auto",
3467
+ "table-fixed": "table-layout:fixed",
3468
+ "align-middle": "vertical-align:middle",
3469
+ "align-top": "vertical-align:top",
3470
+ "align-bottom": "vertical-align:bottom",
3471
+ "align-baseline": "vertical-align:baseline",
3472
+ "list-none": "list-style-type:none",
3473
+ "list-disc": "list-style-type:disc",
3474
+ "list-decimal": "list-style-type:decimal",
3475
+ "appearance-none": "appearance:none",
3476
+ "resize-none": "resize:none",
3477
+ "isolate": "isolation:isolate",
3478
+ "object-cover": "object-fit:cover",
3479
+ "object-contain": "object-fit:contain",
3480
+ "object-center": "object-position:center",
3481
+ "aspect-square": "aspect-ratio:1/1",
3482
+ "aspect-video": "aspect-ratio:16/9",
3483
+ "aspect-auto": "aspect-ratio:auto",
3484
+ "backdrop-blur-sm": "backdrop-filter:blur(4px)",
3485
+ "backdrop-blur": "backdrop-filter:blur(8px)",
3486
+ "backdrop-blur-md": "backdrop-filter:blur(12px)",
3487
+ "backdrop-blur-lg": "backdrop-filter:blur(16px)",
3488
+ "backdrop-blur-xl": "backdrop-filter:blur(24px)",
3489
+ "backdrop-blur-2xl": "backdrop-filter:blur(40px)",
3490
+ "backdrop-blur-3xl": "backdrop-filter:blur(64px)",
3491
+ "backdrop-blur-none": "backdrop-filter:blur(0)",
3492
+ "underline-offset-2": "text-underline-offset:2px",
3493
+ "underline-offset-4": "text-underline-offset:4px",
3494
+ "rounded-xs": "border-radius:var(--radius-xs, 0.125rem)"
3495
+ };
3496
+ ARBITRARY_PROP = {
3497
+ bg: "background",
3498
+ text: "color",
3499
+ w: "width",
3500
+ h: "height",
3501
+ "min-w": "min-width",
3502
+ "max-w": "max-width",
3503
+ "min-h": "min-height",
3504
+ "max-h": "max-height",
3505
+ size: "width",
3506
+ p: "padding",
3507
+ px: "padding-inline",
3508
+ py: "padding-block",
3509
+ pt: "padding-top",
3510
+ pr: "padding-right",
3511
+ pb: "padding-bottom",
3512
+ pl: "padding-left",
3513
+ m: "margin",
3514
+ mx: "margin-inline",
3515
+ my: "margin-block",
3516
+ mt: "margin-top",
3517
+ mr: "margin-right",
3518
+ mb: "margin-bottom",
3519
+ ml: "margin-left",
3520
+ gap: "gap",
3521
+ rounded: "border-radius",
3522
+ shadow: "box-shadow",
3523
+ border: "border-width",
3524
+ top: "top",
3525
+ left: "left",
3526
+ right: "right",
3527
+ bottom: "bottom",
3528
+ inset: "inset",
3529
+ "leading": "line-height",
3530
+ "tracking": "letter-spacing",
3531
+ opacity: "opacity",
3532
+ z: "z-index",
3533
+ grid: "grid-template-columns",
3534
+ "font": "font-size",
3535
+ "aspect": "aspect-ratio",
3536
+ // transition props (transition-[background-color,box-shadow]) + timing
3537
+ transition: "transition-property",
3538
+ duration: "transition-duration",
3539
+ delay: "transition-delay",
3540
+ ease: "transition-timing-function"
3541
+ };
3542
+ MAX_W_SCALE = {
3543
+ xs: "20rem",
3544
+ sm: "24rem",
3545
+ md: "28rem",
3546
+ lg: "32rem",
3547
+ xl: "36rem",
3548
+ "2xl": "42rem",
3549
+ "3xl": "48rem",
3550
+ "4xl": "56rem",
3551
+ "5xl": "64rem",
3552
+ "6xl": "72rem",
3553
+ "7xl": "80rem",
3554
+ prose: "65ch",
3555
+ none: "none"
3556
+ };
3557
+ }
3558
+ });
3559
+
2133
3560
  // ../shared/src/mcp/preview-html.ts
2134
3561
  function cssFromRegistryVars(cssVars) {
2135
3562
  const block = (vars) => Object.entries(vars ?? {}).map(([k, v]) => ` --${k.replace(/^--/, "")}: ${v};`).join("\n");
@@ -2165,11 +3592,14 @@ function addFontFamily(families, raw) {
2165
3592
  if (!family || family.startsWith("var(") || SYSTEM_FONT_FAMILIES.has(family.toLowerCase())) return;
2166
3593
  families.add(family);
2167
3594
  }
3595
+ function stripComments(source) {
3596
+ return source.replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|[^:])\/\/[^\n]*/g, "$1");
3597
+ }
2168
3598
  function componentRadiusCss(files) {
2169
3599
  const radiusFor = (pattern) => {
2170
3600
  const file = files.find((f) => f.path && pattern.test(f.path));
2171
3601
  if (!file?.content) return null;
2172
- const m = file.content.match(/rounded(?:-(?:none|sm|md|lg|xl|2xl|3xl|full))?(?=[\s"'])/);
3602
+ const m = stripComments(file.content).match(/rounded(?:-(?:none|sm|md|lg|xl|2xl|3xl|full))?(?=[\s"'])/);
2173
3603
  return m ? RADIUS_CLASS_TO_CSS[m[0]] ?? null : null;
2174
3604
  };
2175
3605
  const rules = [];
@@ -2181,7 +3611,7 @@ function componentRadiusCss(files) {
2181
3611
  if (card) rules.push(`.bd-card, .ds-card { border-radius: ${card}; }`);
2182
3612
  return rules.join("\n");
2183
3613
  }
2184
- function decodeArbitrary(raw) {
3614
+ function decodeArbitrary2(raw) {
2185
3615
  const value = raw.replace(/(?<!\\)_/g, " ").replace(/\\_/g, "_").trim();
2186
3616
  return value && !/[<>{};]/.test(value) ? value : null;
2187
3617
  }
@@ -2189,12 +3619,12 @@ function restingValue(scope, cssProp, utilPrefixes) {
2189
3619
  for (const prefix of utilPrefixes) {
2190
3620
  const m = scope.match(new RegExp(`(?<![\\w:.\\-])${prefix}-\\[([^\\]]+)\\]`));
2191
3621
  if (m) {
2192
- const v = decodeArbitrary(m[1]);
3622
+ const v = decodeArbitrary2(m[1]);
2193
3623
  if (v) return v;
2194
3624
  }
2195
3625
  }
2196
3626
  const pm = scope.match(new RegExp(`(?<!:)\\[${cssProp}:([^\\]]+)\\]`));
2197
- return pm ? decodeArbitrary(pm[1]) : null;
3627
+ return pm ? decodeArbitrary2(pm[1]) : null;
2198
3628
  }
2199
3629
  function variantBody(content, name) {
2200
3630
  const vi = content.search(/variant\s*:\s*\{/);
@@ -2218,7 +3648,7 @@ function componentDepthCss(files) {
2218
3648
  return rules.join("\n");
2219
3649
  }
2220
3650
  function buildDsComponentCss(files) {
2221
- const contentOf = (re) => files.find((f) => f.path && re.test(f.path))?.content ?? "";
3651
+ const contentOf = (re) => stripComments(files.find((f) => f.path && re.test(f.path))?.content ?? "");
2222
3652
  const has = (name) => Boolean(contentOf(new RegExp(`(^|/)${name}\\.(tsx|jsx)$`)));
2223
3653
  const arbitrary = (scope, re) => {
2224
3654
  const m = scope.match(re);
@@ -2252,9 +3682,102 @@ function buildDsComponentCss(files) {
2252
3682
  const radius = rm ? RADIUS_CLASS_TO_CSS[rm[0]] : null;
2253
3683
  if (radius) rules.push(`.ds-badge, .ds-badge-primary { border-radius: ${radius}; }`);
2254
3684
  }
3685
+ const field = contentOf(/(^|\/)_shared\.(ts|tsx)$/) || contentOf(/(^|\/)input\.(tsx|jsx)$/);
3686
+ if (field) {
3687
+ covered.add("input");
3688
+ const fieldSel = ".ds-input, .ds-textarea, .ds-select";
3689
+ const rm = field.match(/rounded(?:-(?:none|sm|md|lg|xl|2xl|3xl|full))?(?=[\s"'])/);
3690
+ const radius = rm ? RADIUS_CLASS_TO_CSS[rm[0]] : null;
3691
+ if (radius) rules.push(`${fieldSel} { border-radius: ${radius}; }`);
3692
+ const restShadow = restingValue(field, "box-shadow", ["shadow"]);
3693
+ if (restShadow) rules.push(`${fieldSel} { box-shadow: ${restShadow}; }`);
3694
+ const ringAlpha = field.match(/focus-visible:ring-2\s+(?:focus-visible:)?ring-ring\/(\d{1,2})/);
3695
+ if (ringAlpha) {
3696
+ const rest = restShadow ? `${restShadow}, ` : "";
3697
+ rules.push(
3698
+ `.ds-input:focus, .ds-textarea:focus, .ds-select:focus { outline: none; border-color: var(--ring); box-shadow: ${rest}0 0 0 2px color-mix(in oklab, var(--ring) ${ringAlpha[1]}%, transparent); }`
3699
+ );
3700
+ }
3701
+ }
3702
+ const translated = translatedKitComponentCss(contentOf, covered);
3703
+ if (translated) rules.push(translated);
2255
3704
  const excluded = KIT_INTERACTIVE_EXCLUDED.filter((name) => has(name));
2256
3705
  return { css: rules.filter(Boolean).join("\n"), covered: [...covered].sort(), excluded };
2257
3706
  }
3707
+ function quotedStrings(scope) {
3708
+ return [...scope.matchAll(/"([^"]*)"|'([^']*)'/g)].map((m) => m[1] ?? m[2]).join(" ");
3709
+ }
3710
+ function cvaBase(content) {
3711
+ const i = content.search(/\bcva\s*\(/);
3712
+ if (i === -1) return null;
3713
+ const tail = content.slice(i, content.search(/variants\s*:/) !== -1 ? content.search(/variants\s*:/) : void 0);
3714
+ const s = quotedStrings(tail);
3715
+ return s || null;
3716
+ }
3717
+ function kitRuleFromClasses(selector, classString) {
3718
+ const buckets = /* @__PURE__ */ new Map();
3719
+ let usesTwVars = false;
3720
+ for (const cls of new Set(classString.split(/\s+/).filter(Boolean))) {
3721
+ const r = translateClass(cls);
3722
+ if (!r || r.media || r.body === "") continue;
3723
+ const esc = `.${escapeClassName(cls)}`;
3724
+ if (!r.selector.startsWith(esc)) continue;
3725
+ const suffix = r.selector.slice(esc.length);
3726
+ if (r.body.includes("--tw-")) usesTwVars = true;
3727
+ const bucket = buckets.get(suffix) ?? [];
3728
+ bucket.push(r.body.replace(/;\s*$/, ""));
3729
+ buckets.set(suffix, bucket);
3730
+ }
3731
+ const css = [...buckets.entries()].map(([suffix, bodies]) => {
3732
+ const sel = selector.split(",").map((s) => `${s.trim()}${suffix}`).join(", ");
3733
+ return `${sel} { ${bodies.join("; ")} }`;
3734
+ }).join("\n");
3735
+ return { css, usesTwVars };
3736
+ }
3737
+ function translatedKitComponentCss(contentOf, covered) {
3738
+ const out = [];
3739
+ let needsTwDefaults = false;
3740
+ const emit = (selector, classes, component) => {
3741
+ if (!classes) return;
3742
+ const { css, usesTwVars } = kitRuleFromClasses(selector, classes);
3743
+ if (css) {
3744
+ out.push(css);
3745
+ needsTwDefaults ||= usesTwVars;
3746
+ if (component) covered.add(component);
3747
+ }
3748
+ };
3749
+ const badge = contentOf(/(^|\/)badge\.(tsx|jsx)$/);
3750
+ if (badge) {
3751
+ const badgeDefault = variantBody(badge, "default");
3752
+ emit(
3753
+ ".ds-badge",
3754
+ [cvaBase(badge), badgeDefault ? quotedStrings(badgeDefault) : null].filter(Boolean).join(" "),
3755
+ "badge"
3756
+ );
3757
+ }
3758
+ const button = contentOf(/(^|\/)button\.(tsx|jsx)$/);
3759
+ if (button) {
3760
+ emit(".ds-btn", cvaBase(button), "button");
3761
+ emit(".ds-btn-primary", variantBody(button, "primary") ? quotedStrings(variantBody(button, "primary")) : variantBody(button, "default") ? quotedStrings(variantBody(button, "default")) : null);
3762
+ for (const v of ["secondary", "outline", "ghost"]) {
3763
+ const body = variantBody(button, v);
3764
+ if (body) emit(`.ds-btn-${v}`, quotedStrings(body));
3765
+ }
3766
+ }
3767
+ const shared = contentOf(/(^|\/)_shared\.(ts|tsx)$/);
3768
+ const fieldScope = shared.match(/formFieldBase\s*=([\s\S]*?)(?:\nexport |$)/)?.[1] ?? contentOf(/(^|\/)input\.(tsx|jsx)$/);
3769
+ if (fieldScope) {
3770
+ emit(".ds-input, .ds-textarea, .ds-select", quotedStrings(fieldScope), "input");
3771
+ }
3772
+ const card = contentOf(/(^|\/)card\.(tsx|jsx)$/);
3773
+ if (card) {
3774
+ const root = card.match(/cn\(\s*([\s\S]*?)(?:,\s*className|\))/)?.[1];
3775
+ if (root) emit(".ds-card", quotedStrings(root), "card");
3776
+ }
3777
+ if (out.length === 0) return "";
3778
+ return (needsTwDefaults ? `${TW_DEFAULTS}
3779
+ ` : "") + out.join("\n");
3780
+ }
2258
3781
  function extractRadiusScaleCss(rawGlobalsCss) {
2259
3782
  const decls = rawGlobalsCss.match(/--radius-[a-z0-9]+\s*:[^;]+;/g) ?? [];
2260
3783
  return decls.length ? `:root {
@@ -2272,6 +3795,7 @@ var init_preview_html = __esm({
2272
3795
  "../shared/src/mcp/preview-html.ts"() {
2273
3796
  "use strict";
2274
3797
  init_preview_widget_sdk_generated();
3798
+ init_tw_translate();
2275
3799
  init_html_kit();
2276
3800
  SYSTEM_FONT_FAMILIES = /* @__PURE__ */ new Set([
2277
3801
  "arial",
@@ -3044,6 +4568,19 @@ async function fetchCatalog(designSystemId) {
3044
4568
  async function fetchCatalogTokensCss(designSystemId) {
3045
4569
  return (await fetchCatalog(designSystemId)).tokensCss;
3046
4570
  }
4571
+ async function fetchBaseVariantNames(designSystemId) {
4572
+ try {
4573
+ const res = await fetch(`${REGISTRY_BASE_URL}/${designSystemId}/index.json`, {
4574
+ signal: AbortSignal.timeout(5e3)
4575
+ });
4576
+ if (!res.ok) return /* @__PURE__ */ new Set();
4577
+ const parsed = DS_INDEX_SCHEMA.safeParse(await res.json());
4578
+ if (!parsed.success) return /* @__PURE__ */ new Set();
4579
+ return new Set((parsed.data.baseComponents ?? []).map((c) => c.name));
4580
+ } catch {
4581
+ return /* @__PURE__ */ new Set();
4582
+ }
4583
+ }
3047
4584
  function registerDesignSystemTools({
3048
4585
  server,
3049
4586
  provider,
@@ -3054,9 +4591,11 @@ function registerDesignSystemTools({
3054
4591
  const searchInputSchema = z4.object({
3055
4592
  query: z4.string().describe("Natural language query describing the type of UI you're building.")
3056
4593
  });
3057
- const searchDescription = () => `Search the Better Design catalog for an EXISTING design system via semantic search, and return its ID.
4594
+ const searchDescription = () => `Search the Better Design catalog via semantic search and return ranked matches, each with a Preview link.
3058
4595
 
3059
- For building an app, generate the user's OWN brand with create-design-system instead. Use this only to browse or inspect catalog systems (the user names one, or wants to preview before installing).
4596
+ **On a "build/make me <app>" request, call this FIRST.** Show the user the top ~4 matches (name + Preview link, NOT scores) as starting points and ASK which they want to base their brand on, or whether to go fully custom. Then pass the chosen id to create-design-system as \`baseDesignSystemId\`. Don't auto-pick or skip straight to generating, the user should choose the direction.
4597
+
4598
+ Also use it to browse or inspect catalog systems (the user names one, or wants to preview before installing).
3060
4599
 
3061
4600
  Search by:
3062
4601
  - Industry (fintech, education, travel, developer tools)
@@ -3089,23 +4628,21 @@ Examples:
3089
4628
  }
3090
4629
  const formatted = results.map(
3091
4630
  (r) => [
3092
- `**ID:** ${r.id}`,
3093
- `**Title:** ${r.title}`,
3094
- `**Description:** ${r.description}`,
3095
- `**Personality:** ${r.personality.join(", ")}`,
3096
- `**Industry:** ${r.industry.join(", ")}`,
3097
- `**Components:** ${r.componentCount}`,
3098
- `**Match Score:** ${r.matchScore}%`,
3099
- `**Registry:** ${REGISTRY_BASE_URL}/${r.id}`
4631
+ // Markdown link so the NAME is clickable in the host (Claude Code,
4632
+ // ChatGPT, claude.ai all render markdown links). Keep it intact when
4633
+ // presenting so the user can open the preview in one click.
4634
+ `### [${r.title}](${APP_BASE_URL}/design-systems/${r.id})`,
4635
+ `${r.description}`,
4636
+ `_${r.personality.join(", ")}_ \xB7 id: \`${r.id}\``
3100
4637
  ].join("\n")
3101
- ).join("\n\n----------\n\n");
4638
+ ).join("\n\n");
3102
4639
  return finish(
3103
4640
  {
3104
4641
  content: [{
3105
4642
  type: "text",
3106
- text: `# Available Design Systems
4643
+ text: `# Catalog matches
3107
4644
 
3108
- Each result includes an **ID** to use with get-design-system-docs.
4645
+ Present these to the user as options, keeping each name as its clickable markdown link (no scores) so they can open the preview. Ask which to start their brand from, or to go fully custom, then pass the chosen \`id\` as \`baseDesignSystemId\` to create-design-system.
3109
4646
 
3110
4647
  ---
3111
4648
 
@@ -3150,10 +4687,20 @@ full component library available.
3150
4687
 
3151
4688
  Pass 'component' only when the user explicitly asks to inspect or customise a
3152
4689
  specific component's source code. In that mode the tool returns the requested
3153
- components, a scoped install command, and their source code.`,
4690
+ components, a scoped install command, and their source code.
4691
+
4692
+ Base UI (@base-ui/react) is the default flavor. BEFORE installing, inspect the
4693
+ user's project: if package.json has any @radix-ui/* dependency (or
4694
+ components/ui already imports @radix-ui), pass 'library: "radix"' to match their
4695
+ existing setup; otherwise use the default Base UI. Both flavors install to the
4696
+ same components/ui/ paths.
4697
+
4698
+ ${BUILD_TARGET_RULE}`,
3154
4699
  inputSchema: z4.object({
3155
4700
  designSystemId: z4.string().describe("The design system ID from find-design-system"),
3156
- component: z4.union([z4.string(), z4.array(z4.string())]).optional().describe('Optional. Only pass this when the user asks to inspect specific component source code. Examples: "button", ["button", "card"]. Omit to scaffold the entire design system.')
4701
+ component: z4.union([z4.string(), z4.array(z4.string())]).optional().describe('Optional. Only pass this when the user asks to inspect specific component source code. Examples: "button", ["button", "card"]. Omit to scaffold the entire design system.'),
4702
+ library: z4.enum(["radix", "base-ui"]).optional().describe('Optional, default "base-ui". Base UI (@base-ui/react) is the default flavor; pass "radix" to force the Radix flavor when the project already uses Radix primitives. If a design system has no Base UI port yet, the tool falls back to Radix with a note.'),
4703
+ context: CONTEXT_ARG
3157
4704
  }),
3158
4705
  outputSchema: PREVIEW_OUTPUT_SCHEMA,
3159
4706
  annotations: { readOnlyHint: true },
@@ -3163,7 +4710,7 @@ components, a scoped install command, and their source code.`,
3163
4710
  "openai/outputTemplate": DS_PREVIEW_WIDGET_URI
3164
4711
  }
3165
4712
  },
3166
- async ({ designSystemId, component }) => tracked("get-design-system-docs", { designSystemId, component }, async () => {
4713
+ async ({ designSystemId, component, library, context }) => tracked("get-design-system-docs", { designSystemId, component, library, context }, async () => {
3167
4714
  try {
3168
4715
  const system = await provider.getDesignSystemById(designSystemId);
3169
4716
  if (!system) {
@@ -3191,11 +4738,51 @@ components, a scoped install command, and their source code.`,
3191
4738
  if (metadata.borderRadius) header.push(`**Border Radius:** ${metadata.borderRadius}`);
3192
4739
  if (metadata.font) header.push(`**Font:** ${metadata.font}`);
3193
4740
  header.push(`**Preview (see it live):** ${APP_BASE_URL}/design-systems/${metadata.id}`);
4741
+ const wantsBase = library !== "radix";
4742
+ const baseNames = wantsBase ? await fetchBaseVariantNames(metadata.id) : /* @__PURE__ */ new Set();
4743
+ const baseUnavailableNote = wantsBase && baseNames.size === 0 ? `
4744
+ > Note: ${metadata.title} has no Base UI port yet, so the commands below install the Radix components.
4745
+ ` : "";
4746
+ const toInstallName = (name) => baseNames.has(`${name}-base`) ? `${name}-base` : name;
4747
+ const describeInstall = (installNames) => {
4748
+ const componentInstallNames = installNames.filter((name) => name !== "globals");
4749
+ const baseCount = componentInstallNames.filter((name) => name.endsWith("-base")).length;
4750
+ const plainCount = componentInstallNames.length - baseCount;
4751
+ if (!wantsBase) {
4752
+ return {
4753
+ installLibrary: "radix",
4754
+ installNote: "This installs the Radix flavor (matched to the project's existing Radix primitives)."
4755
+ };
4756
+ }
4757
+ if (baseNames.size === 0) {
4758
+ return {
4759
+ installLibrary: "radix",
4760
+ installNote: "This installs the Radix flavor because this design system has no Base UI port yet."
4761
+ };
4762
+ }
4763
+ if (baseCount > 0 && plainCount > 0) {
4764
+ return {
4765
+ installLibrary: "mixed",
4766
+ installNote: 'This installs the Base UI flavor where available, plus plain registry entries for components without a Base UI twin. If the project uses Radix, re-run this tool with `library: "radix"` instead.'
4767
+ };
4768
+ }
4769
+ if (baseCount > 0) {
4770
+ return {
4771
+ installLibrary: "base-ui",
4772
+ installNote: 'This installs the Base UI flavor (the default). If the project uses Radix, re-run this tool with `library: "radix"` instead.'
4773
+ };
4774
+ }
4775
+ return {
4776
+ installLibrary: "radix",
4777
+ installNote: "This installs plain registry entries because the requested components do not have Base UI twins yet."
4778
+ };
4779
+ };
3194
4780
  if (!component) {
3195
4781
  const installNames = [
3196
4782
  "globals",
3197
- ...allComponents.map((c) => c.name).sort()
4783
+ ...allComponents.map((c) => toInstallName(c.name)).sort()
3198
4784
  ];
4785
+ const { installLibrary: installLibrary2, installNote: installNote2 } = describeInstall(installNames);
3199
4786
  const installUrls = installNames.map((name) => `${REGISTRY_BASE_URL}/${metadata.id}/${name}.json`).join(" \\\n ");
3200
4787
  const installCommand2 = `npx shadcn@latest add \\
3201
4788
  ${installUrls}`;
@@ -3203,6 +4790,7 @@ components, a scoped install command, and their source code.`,
3203
4790
  const parts2 = [
3204
4791
  ...header,
3205
4792
  "\n## Scaffold the full design system\n",
4793
+ ...baseUnavailableNote ? [baseUnavailableNote] : [],
3206
4794
  "_This is the React path, the right call whenever you have a filesystem + terminal. Build real components from `components/ui/`. Only fall back to `get-design-system-html` for inline chat canvases (ChatGPT / Claude artifacts) that cannot run a build._\n",
3207
4795
  REQUIREMENTS_MD,
3208
4796
  `Run these commands in the user's project root. The first **conditionally** runs \`shadcn init\` only when the project hasn't been set up yet (no \`components.json\`); the second installs **all ${installNames.length} pieces** (globals.css + ${allComponents.length} components) into \`components/ui/\` with a single shadcn invocation:`,
@@ -3214,6 +4802,8 @@ components, a scoped install command, and their source code.`,
3214
4802
  `# 2. Install Better Design's full DS into components/ui/`,
3215
4803
  installCommand2,
3216
4804
  "```",
4805
+ `
4806
+ _${installNote2}_`,
3217
4807
  ANTI_MOCKUP_MD,
3218
4808
  "\nAfter the install completes, read files from `components/ui/` directly when writing feature code. Do not ask this tool for component source unless the user wants to inspect or customise a specific file.",
3219
4809
  "\n## Included components\n",
@@ -3222,7 +4812,12 @@ components, a scoped install command, and their source code.`,
3222
4812
  ];
3223
4813
  return {
3224
4814
  content: [{ type: "text", text: parts2.join("\n") }],
3225
- structuredContent: { ...previewStructured, installCommand: structuredInstallCommand2 }
4815
+ structuredContent: {
4816
+ ...previewStructured,
4817
+ installCommand: structuredInstallCommand2,
4818
+ installLibrary: installLibrary2,
4819
+ installNote: installNote2
4820
+ }
3226
4821
  };
3227
4822
  }
3228
4823
  const componentNames = Array.isArray(component) ? component : [component];
@@ -3249,13 +4844,16 @@ components, a scoped install command, and their source code.`,
3249
4844
  }
3250
4845
  };
3251
4846
  }
3252
- const scopedUrls = resolvedNames.map((name) => `${REGISTRY_BASE_URL}/${metadata.id}/${name}.json`).join(" \\\n ");
4847
+ const scopedInstallNames = resolvedNames.map((name) => toInstallName(name));
4848
+ const { installLibrary, installNote } = describeInstall(scopedInstallNames);
4849
+ const scopedUrls = scopedInstallNames.map((name) => `${REGISTRY_BASE_URL}/${metadata.id}/${name}.json`).join(" \\\n ");
3253
4850
  const installCommand = `npx shadcn@latest add \\
3254
4851
  ${scopedUrls}`;
3255
4852
  const structuredInstallCommand = installCommandWithInit(installCommand);
3256
4853
  const parts = [
3257
4854
  ...header,
3258
4855
  "\n## Install just these components\n",
4856
+ ...baseUnavailableNote ? [baseUnavailableNote] : [],
3259
4857
  REQUIREMENTS_MD,
3260
4858
  "```bash",
3261
4859
  `# Init shadcn if missing (idempotent, skips when components.json exists)`,
@@ -3263,6 +4861,8 @@ components, a scoped install command, and their source code.`,
3263
4861
  "",
3264
4862
  installCommand,
3265
4863
  "```",
4864
+ `
4865
+ _${installNote}_`,
3266
4866
  ANTI_MOCKUP_MD,
3267
4867
  "\n---\n"
3268
4868
  ];
@@ -3278,7 +4878,12 @@ components, a scoped install command, and their source code.`,
3278
4878
  }
3279
4879
  return {
3280
4880
  content: [{ type: "text", text: parts.join("\n") }],
3281
- structuredContent: { ...previewStructured, installCommand: structuredInstallCommand }
4881
+ structuredContent: {
4882
+ ...previewStructured,
4883
+ installCommand: structuredInstallCommand,
4884
+ installLibrary,
4885
+ installNote
4886
+ }
3282
4887
  };
3283
4888
  } catch (error) {
3284
4889
  return {
@@ -3294,7 +4899,7 @@ components, a scoped install command, and their source code.`,
3294
4899
  title: "Create a New Design System",
3295
4900
  description: `Generate a brand new design system tailored to the user's product, and return a single shadcn install command that lands the entire set of components + tokens (globals.css) into the user's Next.js project.
3296
4901
 
3297
- **Use this PROACTIVELY on any "build/make me <app>" request \u2014 even when the user never mentions design or branding.** A design system IS the app's brand/visual identity, so creating one first is the right first step for building an app: derive the \`prompt\` from the app (its name, domain, and vibe), generate the brand, show it with \`get-design-system-status\`, then build the app with that brand. Also use it when the user explicitly wants a **custom** design system instead of installing an existing one via 'get-design-system-docs'.
4902
+ **Use this on any "build/make me <app>" request \u2014 even when the user never mentions design or branding** (a design system IS the app's brand). But DON'T jump straight here: first call \`find-design-system\` with the app description, show the user the top ~4 matches, and ask which to start from (passed here as \`baseDesignSystemId\`) or whether to go fully custom. Then derive the \`prompt\` from the app (name, domain, vibe), generate, show it with \`get-design-system-status\`, and build with that brand. Also use it when the user explicitly wants a **custom** design system instead of installing an existing one via 'get-design-system-docs'.
3298
4903
 
3299
4904
  How it works:
3300
4905
  1. Sends the user's prompt to Better Design's generation pipeline (same flow the web chat input uses) and returns IMMEDIATELY with the project id + project URL.
@@ -3304,7 +4909,7 @@ How it works:
3304
4909
  Share the project URL with the user right away so they can watch the generation live.`,
3305
4910
  inputSchema: z4.object({
3306
4911
  prompt: z4.string().min(1).max(1e4).describe("Describe the design system the user wants. E.g. 'A warm, minimal design system for a personal finance app, soft pastels, rounded corners' or 'A brutalist developer tool aesthetic with sharp edges and monospace type'."),
3307
- baseDesignSystemId: z4.string().optional().describe("Optional. Pass a design system ID from `find-design-system` to bias generation toward an existing aesthetic (e.g. apply a theme tweak on top of Linear). Leave empty for a fully custom DS.")
4912
+ baseDesignSystemId: z4.string().optional().describe("Optional. The catalog id the USER picked from the `find-design-system` matches you showed them, used to bias generation toward that aesthetic (e.g. a theme tweak on top of Linear). Leave empty only when the user chose fully custom.")
3308
4913
  }),
3309
4914
  annotations: {
3310
4915
  readOnlyHint: false,
@@ -3407,7 +5012,9 @@ npx shadcn@latest add ${registryUrl}
3407
5012
  ANTI_MOCKUP_MD,
3408
5013
  inlineBuildMd(projectId),
3409
5014
  "",
3410
- `In a real codebase, run the install above; do NOT hand-build an HTML/React copy of the components. The preview widget already shows it, and ${projectUrl} has the full showcase.`
5015
+ `In a real codebase, run the install above; do NOT hand-build an HTML/React copy of the components. The preview widget already shows it, and ${projectUrl} has the full showcase.`,
5016
+ "",
5017
+ `Now help the user finish, don't stop here. No icon library has been picked yet: call \`find-icon-library\` (query from the brand's personality), SHOW them the closest matches and let them pick one, then \`install-icons\`. After that, ask if they want to start building components.`
3411
5018
  ];
3412
5019
  const previewUrl = project.previewFragmentId ? `${APP_BASE_URL}/preview/${project.previewFragmentId}` : projectUrl;
3413
5020
  const shotUrl = project.previewFragmentId ? `${APP_BASE_URL}/api/og/preview?fragment=${project.previewFragmentId}` : void 0;
@@ -3446,9 +5053,10 @@ Check again in ~30 seconds. Watch it live on the project page: ${projectUrl}` }]
3446
5053
  };
3447
5054
  const statusConfig = {
3448
5055
  title: "Get Design System Generation Status",
3449
- description: `Check on a design system generation started with 'create-design-system'. Returns progress while generating, and the live preview URL + the \`npx shadcn add\` install command once complete. Generation typically takes 1-3 minutes; poll every ~30 seconds until it reports ready.`,
5056
+ description: `Check on a design system generation started with 'create-design-system'. Returns progress while generating, and the live preview URL + the \`npx shadcn add\` install command once complete. Generation typically takes 1-3 minutes; poll every ~30 seconds until it reports ready. Once ready, ask the user what's next (icon library, install, or build) instead of stopping.`,
3450
5057
  inputSchema: z4.object({
3451
- projectId: z4.string().min(1).describe("The project id returned by create-design-system.")
5058
+ projectId: z4.string().min(1).describe("The project id returned by create-design-system."),
5059
+ context: CONTEXT_ARG
3452
5060
  }),
3453
5061
  outputSchema: PREVIEW_OUTPUT_SCHEMA,
3454
5062
  annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: false },
@@ -3463,7 +5071,7 @@ Check again in ~30 seconds. Watch it live on the project page: ${projectUrl}` }]
3463
5071
  server.registerTool(
3464
5072
  "get-design-system-status",
3465
5073
  statusConfig,
3466
- ({ projectId }) => tracked("get-design-system-status", {}, () => runDesignSystemStatus(projectId))
5074
+ ({ projectId, context }) => tracked("get-design-system-status", { context }, () => runDesignSystemStatus(projectId))
3467
5075
  );
3468
5076
  server.registerTool(
3469
5077
  "preview-design-system",
@@ -3471,7 +5079,8 @@ Check again in ~30 seconds. Watch it live on the project page: ${projectUrl}` }]
3471
5079
  title: "Preview a Design System",
3472
5080
  description: `Show the user a visual preview of a design system from the catalog (use the id from 'find-design-system'). Returns a token-true HTML preview: palette, typography, buttons, card, input, badge, plus a link to the full live showcase. Use this when the user wants to SEE a design system before installing it.`,
3473
5081
  inputSchema: z4.object({
3474
- designSystemId: z4.string().min(1).describe("Design system id from find-design-system, e.g. 'linear', 'editorial-warm'.")
5082
+ designSystemId: z4.string().min(1).describe("Design system id from find-design-system, e.g. 'linear', 'editorial-warm'."),
5083
+ context: CONTEXT_ARG
3475
5084
  }),
3476
5085
  outputSchema: PREVIEW_OUTPUT_SCHEMA,
3477
5086
  annotations: {
@@ -3487,7 +5096,7 @@ Check again in ~30 seconds. Watch it live on the project page: ${projectUrl}` }]
3487
5096
  "openai/toolInvocation/invoked": "Preview ready"
3488
5097
  }
3489
5098
  },
3490
- async ({ designSystemId }) => tracked("preview-design-system", { designSystemId }, async () => {
5099
+ async ({ designSystemId, context }) => tracked("preview-design-system", { designSystemId, context }, async () => {
3491
5100
  const ds = await provider.getDesignSystemById(designSystemId);
3492
5101
  if (!ds) {
3493
5102
  return {
@@ -3532,12 +5141,15 @@ Check again in ~30 seconds. Watch it live on the project page: ${projectUrl}` }]
3532
5141
  title: "Get a Design System as HTML/CSS",
3533
5142
  description: `Export a design system as plain, framework-free HTML + CSS for building an app INLINE (ChatGPT canvas / Claude artifact) where npm and a Tailwind build are unavailable. Returns the system's real design tokens (globals.css) plus a token-driven component CSS kit (button, input, card, badge, alert, etc.) and an example to riff on.
3534
5143
 
5144
+ The response ends with a usage guide ("How to use"). Follow EVERY rule in it when building: paste the CSS blocks verbatim (never retype them), compose ONLY the \`ds-*\` component classes (custom classes are for layout only), and wire the few lines of JS that make controls actually work. The guide is the contract that keeps the build on-brand; never restyle the components it ships.
5145
+
3535
5146
  Works for BOTH a catalog system (pass \`designSystemId\` from find-design-system) AND a custom system you just generated (pass \`projectId\` from create-design-system / get-design-system-status).
3536
5147
 
3537
5148
  ${BUILD_TARGET_RULE}`,
3538
5149
  inputSchema: z4.object({
3539
5150
  designSystemId: z4.string().min(1).optional().describe("Catalog design system id from find-design-system, e.g. 'linear', 'editorial-warm'. Pass this OR projectId."),
3540
- projectId: z4.string().min(1).optional().describe("Project id from create-design-system / get-design-system-status, for a custom generated DS. Pass this OR designSystemId.")
5151
+ projectId: z4.string().min(1).optional().describe("Project id from create-design-system / get-design-system-status, for a custom generated DS. Pass this OR designSystemId."),
5152
+ context: CONTEXT_ARG
3541
5153
  }),
3542
5154
  annotations: {
3543
5155
  readOnlyHint: true,
@@ -3545,7 +5157,7 @@ ${BUILD_TARGET_RULE}`,
3545
5157
  openWorldHint: false
3546
5158
  }
3547
5159
  },
3548
- async ({ designSystemId, projectId }) => tracked("get-design-system-html", { designSystemId, projectId }, async () => {
5160
+ async ({ designSystemId, projectId, context }) => tracked("get-design-system-html", { designSystemId, projectId, context }, async () => {
3549
5161
  if (projectId) {
3550
5162
  const result = await fetchProjectTokensCss(projectId, authContext);
3551
5163
  const viewUrl2 = `${APP_BASE_URL}/projects/${projectId}`;
@@ -3582,7 +5194,9 @@ ${BUILD_TARGET_RULE}`,
3582
5194
  const fence2 = "`".repeat(Math.max(3, longestRun + 1));
3583
5195
  return { content: [{ type: "text", text: `${steer}${intro}${fence2}html
3584
5196
  ${ds.metadata.html}
3585
- ${fence2}` }] };
5197
+ ${fence2}
5198
+
5199
+ ${HTML_KIT_CONDUCT_MD}` }] };
3586
5200
  }
3587
5201
  const { tokensCss, files } = await fetchCatalog(designSystemId);
3588
5202
  if (!tokensCss) {
@@ -3596,7 +5210,7 @@ ${fence2}` }] };
3596
5210
  })
3597
5211
  );
3598
5212
  }
3599
- var REGISTRY_ITEM_SCHEMA, SHADCN_INIT_IF_MISSING, SAFE_COMPONENT_NAME_RE, CATALOG_KIT_COMPONENTS;
5213
+ var REGISTRY_ITEM_SCHEMA, SHADCN_INIT_IF_MISSING, SAFE_COMPONENT_NAME_RE, CATALOG_KIT_COMPONENTS, DS_INDEX_SCHEMA;
3600
5214
  var init_design_system_tools = __esm({
3601
5215
  "../shared/src/mcp/tools/design-system-tools.ts"() {
3602
5216
  "use strict";
@@ -3615,6 +5229,572 @@ var init_design_system_tools = __esm({
3615
5229
  SHADCN_INIT_IF_MISSING = "[ -f components.json ] || npx shadcn@latest init -d -y";
3616
5230
  SAFE_COMPONENT_NAME_RE = /^[a-z0-9][a-z0-9-]*$/i;
3617
5231
  CATALOG_KIT_COMPONENTS = ["button", "input", "card", "badge", "switch"];
5232
+ DS_INDEX_SCHEMA = z4.object({
5233
+ baseComponents: z4.array(z4.object({ name: z4.string() })).optional()
5234
+ });
5235
+ }
5236
+ });
5237
+
5238
+ // ../shared/src/registry-css.ts
5239
+ function parseCssVars(css) {
5240
+ const out = { theme: {}, light: {}, dark: {} };
5241
+ const matchBlock = (selector) => {
5242
+ const re = new RegExp(`${selector}\\s*\\{([^}]*)\\}`, "g");
5243
+ const blocks = [];
5244
+ let m;
5245
+ while (m = re.exec(css)) blocks.push(m[1]);
5246
+ return blocks.join("\n");
5247
+ };
5248
+ const extract = (body) => {
5249
+ const result = {};
5250
+ const clean = body.replace(/\/\*[\s\S]*?\*\//g, "");
5251
+ const declRe = /--([a-zA-Z0-9_-]+)\s*:\s*([^;]+);/g;
5252
+ let m;
5253
+ while (m = declRe.exec(clean)) {
5254
+ result[m[1]] = m[2].replace(/\s+/g, " ").trim();
5255
+ }
5256
+ return result;
5257
+ };
5258
+ out.light = extract(matchBlock(":root"));
5259
+ out.dark = extract(matchBlock("\\.dark"));
5260
+ return out;
5261
+ }
5262
+ var init_registry_css = __esm({
5263
+ "../shared/src/registry-css.ts"() {
5264
+ "use strict";
5265
+ }
5266
+ });
5267
+
5268
+ // ../shared/src/mcp/color-to-oklch.ts
5269
+ function clamp01(n) {
5270
+ return Math.min(1, Math.max(0, n));
5271
+ }
5272
+ function round(n, places) {
5273
+ const f = 10 ** places;
5274
+ return Math.round(n * f) / f;
5275
+ }
5276
+ function parseAlpha(raw) {
5277
+ if (raw == null) return 1;
5278
+ const s = raw.trim();
5279
+ if (s.endsWith("%")) return clamp01(parseFloat(s) / 100);
5280
+ const n = parseFloat(s);
5281
+ return Number.isFinite(n) ? clamp01(n) : 1;
5282
+ }
5283
+ function parseChannel(raw) {
5284
+ const s = raw.trim();
5285
+ if (s.endsWith("%")) return clamp01(parseFloat(s) / 100);
5286
+ return clamp01(parseFloat(s) / 255);
5287
+ }
5288
+ function parseHex(hex) {
5289
+ let h = hex.trim().replace(/^#/, "");
5290
+ if (![3, 4, 6, 8].includes(h.length) || /[^0-9a-fA-F]/.test(h)) return null;
5291
+ if (h.length === 3 || h.length === 4) {
5292
+ h = h.split("").map((c) => c + c).join("");
5293
+ }
5294
+ const r = parseInt(h.slice(0, 2), 16) / 255;
5295
+ const g = parseInt(h.slice(2, 4), 16) / 255;
5296
+ const b = parseInt(h.slice(4, 6), 16) / 255;
5297
+ const a = h.length === 8 ? parseInt(h.slice(6, 8), 16) / 255 : 1;
5298
+ return { r, g, b, a };
5299
+ }
5300
+ function splitColorArgs(inner) {
5301
+ let alpha;
5302
+ let body = inner;
5303
+ const slash = inner.indexOf("/");
5304
+ if (slash !== -1) {
5305
+ alpha = inner.slice(slash + 1);
5306
+ body = inner.slice(0, slash);
5307
+ }
5308
+ const parts = body.trim().split(/[\s,]+/).filter(Boolean);
5309
+ if (alpha === void 0 && parts.length === 4) {
5310
+ alpha = parts.pop();
5311
+ }
5312
+ return { parts, alpha };
5313
+ }
5314
+ function finiteRgba(rgba) {
5315
+ return [rgba.r, rgba.g, rgba.b, rgba.a].every((n) => Number.isFinite(n)) ? rgba : null;
5316
+ }
5317
+ function parseRgb(value) {
5318
+ const m = value.match(/^rgba?\(([^)]+)\)$/i);
5319
+ if (!m) return null;
5320
+ const { parts, alpha } = splitColorArgs(m[1]);
5321
+ if (parts.length < 3) return null;
5322
+ return finiteRgba({
5323
+ r: parseChannel(parts[0]),
5324
+ g: parseChannel(parts[1]),
5325
+ b: parseChannel(parts[2]),
5326
+ a: parseAlpha(alpha)
5327
+ });
5328
+ }
5329
+ function hueToRgb(p, q, t) {
5330
+ let tt = t;
5331
+ if (tt < 0) tt += 1;
5332
+ if (tt > 1) tt -= 1;
5333
+ if (tt < 1 / 6) return p + (q - p) * 6 * tt;
5334
+ if (tt < 1 / 2) return q;
5335
+ if (tt < 2 / 3) return p + (q - p) * (2 / 3 - tt) * 6;
5336
+ return p;
5337
+ }
5338
+ function parseHue(raw) {
5339
+ const s = raw.trim().toLowerCase();
5340
+ const n = parseFloat(s);
5341
+ if (!Number.isFinite(n)) return NaN;
5342
+ if (s.endsWith("turn")) return n * 360;
5343
+ if (s.endsWith("grad")) return n * 0.9;
5344
+ if (s.endsWith("rad")) return n * (180 / Math.PI);
5345
+ return n;
5346
+ }
5347
+ function parseHsl(value) {
5348
+ const m = value.match(/^hsla?\(([^)]+)\)$/i);
5349
+ if (!m) return null;
5350
+ const { parts, alpha } = splitColorArgs(m[1]);
5351
+ if (parts.length < 3) return null;
5352
+ const hRaw = parseHue(parts[0]);
5353
+ const sRaw = parseFloat(parts[1]);
5354
+ const lRaw = parseFloat(parts[2]);
5355
+ if (![hRaw, sRaw, lRaw].every((n) => Number.isFinite(n))) return null;
5356
+ const h = (hRaw % 360 + 360) % 360 / 360;
5357
+ const s = clamp01(sRaw / 100);
5358
+ const l = clamp01(lRaw / 100);
5359
+ let r;
5360
+ let g;
5361
+ let b;
5362
+ if (s === 0) {
5363
+ r = g = b = l;
5364
+ } else {
5365
+ const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
5366
+ const p = 2 * l - q;
5367
+ r = hueToRgb(p, q, h + 1 / 3);
5368
+ g = hueToRgb(p, q, h);
5369
+ b = hueToRgb(p, q, h - 1 / 3);
5370
+ }
5371
+ return { r, g, b, a: parseAlpha(alpha) };
5372
+ }
5373
+ function srgbToLinear(c) {
5374
+ return c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
5375
+ }
5376
+ function rgbaToOklch({ r, g, b, a }) {
5377
+ const lr = srgbToLinear(r);
5378
+ const lg = srgbToLinear(g);
5379
+ const lb = srgbToLinear(b);
5380
+ const l = 0.4122214708 * lr + 0.5363325363 * lg + 0.0514459929 * lb;
5381
+ const m = 0.2119034982 * lr + 0.6806995451 * lg + 0.1073969566 * lb;
5382
+ const s = 0.0883024619 * lr + 0.2817188376 * lg + 0.6299787005 * lb;
5383
+ const l_ = Math.cbrt(l);
5384
+ const m_ = Math.cbrt(m);
5385
+ const s_ = Math.cbrt(s);
5386
+ const L = 0.2104542553 * l_ + 0.793617785 * m_ - 0.0040720468 * s_;
5387
+ const aa = 1.9779984951 * l_ - 2.428592205 * m_ + 0.4505937099 * s_;
5388
+ const bb = 0.0259040371 * l_ + 0.7827717662 * m_ - 0.808675766 * s_;
5389
+ const C = Math.sqrt(aa * aa + bb * bb);
5390
+ let h = Math.atan2(bb, aa) * 180 / Math.PI;
5391
+ if (h < 0) h += 360;
5392
+ const Lr = round(clamp01(L), 4);
5393
+ const Cr = round(Math.max(0, C), 4);
5394
+ const hr = Cr < 5e-4 ? 0 : round(h, 2);
5395
+ const core = `${Lr} ${Cr} ${hr}`;
5396
+ return a < 1 ? `oklch(${core} / ${round(a, 3)})` : `oklch(${core})`;
5397
+ }
5398
+ function toOklch(value) {
5399
+ const v = value.trim();
5400
+ if (!v) return null;
5401
+ const lower = v.toLowerCase();
5402
+ if (lower.startsWith("oklch(")) return v;
5403
+ if (lower === "transparent") return "oklch(0 0 0 / 0)";
5404
+ if (PASSTHROUGH_KEYWORDS.has(lower)) return v;
5405
+ if (NON_COLOR_KEYWORDS.has(lower)) return null;
5406
+ const named = NAMED_HEX[lower];
5407
+ if (named) {
5408
+ const rgbaNamed = parseHex(named);
5409
+ if (rgbaNamed) return rgbaToOklch(rgbaNamed);
5410
+ }
5411
+ let rgba = null;
5412
+ if (v.startsWith("#")) rgba = parseHex(v);
5413
+ else if (/^rgba?\(/i.test(v)) rgba = parseRgb(v);
5414
+ else if (/^hsla?\(/i.test(v)) rgba = parseHsl(v);
5415
+ return rgba ? rgbaToOklch(rgba) : null;
5416
+ }
5417
+ var NAMED_HEX, PASSTHROUGH_KEYWORDS, NON_COLOR_KEYWORDS;
5418
+ var init_color_to_oklch = __esm({
5419
+ "../shared/src/mcp/color-to-oklch.ts"() {
5420
+ "use strict";
5421
+ NAMED_HEX = {
5422
+ aliceblue: "#f0f8ff",
5423
+ antiquewhite: "#faebd7",
5424
+ aqua: "#00ffff",
5425
+ aquamarine: "#7fffd4",
5426
+ azure: "#f0ffff",
5427
+ beige: "#f5f5dc",
5428
+ bisque: "#ffe4c4",
5429
+ black: "#000000",
5430
+ blanchedalmond: "#ffebcd",
5431
+ blue: "#0000ff",
5432
+ blueviolet: "#8a2be2",
5433
+ brown: "#a52a2a",
5434
+ burlywood: "#deb887",
5435
+ cadetblue: "#5f9ea0",
5436
+ chartreuse: "#7fff00",
5437
+ chocolate: "#d2691e",
5438
+ coral: "#ff7f50",
5439
+ cornflowerblue: "#6495ed",
5440
+ cornsilk: "#fff8dc",
5441
+ crimson: "#dc143c",
5442
+ cyan: "#00ffff",
5443
+ darkblue: "#00008b",
5444
+ darkcyan: "#008b8b",
5445
+ darkgoldenrod: "#b8860b",
5446
+ darkgray: "#a9a9a9",
5447
+ darkgreen: "#006400",
5448
+ darkgrey: "#a9a9a9",
5449
+ darkkhaki: "#bdb76b",
5450
+ darkmagenta: "#8b008b",
5451
+ darkolivegreen: "#556b2f",
5452
+ darkorange: "#ff8c00",
5453
+ darkorchid: "#9932cc",
5454
+ darkred: "#8b0000",
5455
+ darksalmon: "#e9967a",
5456
+ darkseagreen: "#8fbc8f",
5457
+ darkslateblue: "#483d8b",
5458
+ darkslategray: "#2f4f4f",
5459
+ darkslategrey: "#2f4f4f",
5460
+ darkturquoise: "#00ced1",
5461
+ darkviolet: "#9400d3",
5462
+ deeppink: "#ff1493",
5463
+ deepskyblue: "#00bfff",
5464
+ dimgray: "#696969",
5465
+ dimgrey: "#696969",
5466
+ dodgerblue: "#1e90ff",
5467
+ firebrick: "#b22222",
5468
+ floralwhite: "#fffaf0",
5469
+ forestgreen: "#228b22",
5470
+ fuchsia: "#ff00ff",
5471
+ gainsboro: "#dcdcdc",
5472
+ ghostwhite: "#f8f8ff",
5473
+ gold: "#ffd700",
5474
+ goldenrod: "#daa520",
5475
+ gray: "#808080",
5476
+ green: "#008000",
5477
+ greenyellow: "#adff2f",
5478
+ grey: "#808080",
5479
+ honeydew: "#f0fff0",
5480
+ hotpink: "#ff69b4",
5481
+ indianred: "#cd5c5c",
5482
+ indigo: "#4b0082",
5483
+ ivory: "#fffff0",
5484
+ khaki: "#f0e68c",
5485
+ lavender: "#e6e6fa",
5486
+ lavenderblush: "#fff0f5",
5487
+ lawngreen: "#7cfc00",
5488
+ lemonchiffon: "#fffacd",
5489
+ lightblue: "#add8e6",
5490
+ lightcoral: "#f08080",
5491
+ lightcyan: "#e0ffff",
5492
+ lightgoldenrodyellow: "#fafad2",
5493
+ lightgray: "#d3d3d3",
5494
+ lightgreen: "#90ee90",
5495
+ lightgrey: "#d3d3d3",
5496
+ lightpink: "#ffb6c1",
5497
+ lightsalmon: "#ffa07a",
5498
+ lightseagreen: "#20b2aa",
5499
+ lightskyblue: "#87cefa",
5500
+ lightslategray: "#778899",
5501
+ lightslategrey: "#778899",
5502
+ lightsteelblue: "#b0c4de",
5503
+ lightyellow: "#ffffe0",
5504
+ lime: "#00ff00",
5505
+ limegreen: "#32cd32",
5506
+ linen: "#faf0e6",
5507
+ magenta: "#ff00ff",
5508
+ maroon: "#800000",
5509
+ mediumaquamarine: "#66cdaa",
5510
+ mediumblue: "#0000cd",
5511
+ mediumorchid: "#ba55d3",
5512
+ mediumpurple: "#9370db",
5513
+ mediumseagreen: "#3cb371",
5514
+ mediumslateblue: "#7b68ee",
5515
+ mediumspringgreen: "#00fa9a",
5516
+ mediumturquoise: "#48d1cc",
5517
+ mediumvioletred: "#c71585",
5518
+ midnightblue: "#191970",
5519
+ mintcream: "#f5fffa",
5520
+ mistyrose: "#ffe4e1",
5521
+ moccasin: "#ffe4b5",
5522
+ navajowhite: "#ffdead",
5523
+ navy: "#000080",
5524
+ oldlace: "#fdf5e6",
5525
+ olive: "#808000",
5526
+ olivedrab: "#6b8e23",
5527
+ orange: "#ffa500",
5528
+ orangered: "#ff4500",
5529
+ orchid: "#da70d6",
5530
+ palegoldenrod: "#eee8aa",
5531
+ palegreen: "#98fb98",
5532
+ paleturquoise: "#afeeee",
5533
+ palevioletred: "#db7093",
5534
+ papayawhip: "#ffefd5",
5535
+ peachpuff: "#ffdab9",
5536
+ peru: "#cd853f",
5537
+ pink: "#ffc0cb",
5538
+ plum: "#dda0dd",
5539
+ powderblue: "#b0e0e6",
5540
+ purple: "#800080",
5541
+ rebeccapurple: "#663399",
5542
+ red: "#ff0000",
5543
+ rosybrown: "#bc8f8f",
5544
+ royalblue: "#4169e1",
5545
+ saddlebrown: "#8b4513",
5546
+ salmon: "#fa8072",
5547
+ sandybrown: "#f4a460",
5548
+ seagreen: "#2e8b57",
5549
+ seashell: "#fff5ee",
5550
+ sienna: "#a0522d",
5551
+ silver: "#c0c0c0",
5552
+ skyblue: "#87ceeb",
5553
+ slateblue: "#6a5acd",
5554
+ slategray: "#708090",
5555
+ slategrey: "#708090",
5556
+ snow: "#fffafa",
5557
+ springgreen: "#00ff7f",
5558
+ steelblue: "#4682b4",
5559
+ tan: "#d2b48c",
5560
+ teal: "#008080",
5561
+ thistle: "#d8bfd8",
5562
+ tomato: "#ff6347",
5563
+ turquoise: "#40e0d0",
5564
+ violet: "#ee82ee",
5565
+ wheat: "#f5deb3",
5566
+ white: "#ffffff",
5567
+ whitesmoke: "#f5f5f5",
5568
+ yellow: "#ffff00",
5569
+ yellowgreen: "#9acd32"
5570
+ };
5571
+ PASSTHROUGH_KEYWORDS = /* @__PURE__ */ new Set(["currentcolor"]);
5572
+ NON_COLOR_KEYWORDS = /* @__PURE__ */ new Set(["inherit", "initial", "unset"]);
5573
+ }
5574
+ });
5575
+
5576
+ // ../shared/src/mcp/extract-design-system.ts
5577
+ function classify(name, value) {
5578
+ const n = name.toLowerCase();
5579
+ if (n.includes("shadow")) return "shadow";
5580
+ if (n.includes("font")) return "font";
5581
+ if (n.includes("radius")) return "radius";
5582
+ if (toOklch(value) !== null) return "color";
5583
+ return "other";
5584
+ }
5585
+ function extractThemeBlock(css) {
5586
+ const out = {};
5587
+ const stripped = css.replace(/\/\*[\s\S]*?\*\//g, "");
5588
+ const re = /@theme[^{]*\{([^}]*)\}/g;
5589
+ let block;
5590
+ while (block = re.exec(stripped)) {
5591
+ const declRe = /--([a-zA-Z0-9_-]+)\s*:\s*([^;}]+);?/g;
5592
+ let m;
5593
+ while (m = declRe.exec(block[1])) {
5594
+ out[m[1]] = m[2].replace(/\s+/g, " ").trim();
5595
+ }
5596
+ }
5597
+ return out;
5598
+ }
5599
+ function denamespace(name) {
5600
+ return name.replace(/^color-/, "");
5601
+ }
5602
+ function normalizeMap(raw) {
5603
+ const tokens = {};
5604
+ const kinds = {};
5605
+ for (const [rawName, value] of Object.entries(raw)) {
5606
+ const kind = classify(rawName, value);
5607
+ const normalizedValue = kind === "color" ? toOklch(value) ?? value : value;
5608
+ tokens[rawName] = normalizedValue;
5609
+ kinds[rawName] = kind;
5610
+ }
5611
+ return { tokens, kinds };
5612
+ }
5613
+ function extractDesignSystem(css, name) {
5614
+ const { light: rootLight, dark: rootDark } = parseCssVars(css);
5615
+ const themeVars = extractThemeBlock(css);
5616
+ const mergedLight = {};
5617
+ for (const [k, v] of Object.entries(themeVars)) {
5618
+ mergedLight[denamespace(k)] = v;
5619
+ }
5620
+ Object.assign(mergedLight, rootLight);
5621
+ const light = normalizeMap(mergedLight);
5622
+ const dark = normalizeMap(rootDark);
5623
+ const hasLight = Object.keys(light.tokens).length > 0;
5624
+ const hasDark = Object.keys(dark.tokens).length > 0;
5625
+ const themeMode = hasLight && hasDark ? "dual" : hasDark ? "dark" : hasLight ? "light" : "none";
5626
+ const primaryKinds = hasLight ? light.kinds : dark.kinds;
5627
+ return {
5628
+ name,
5629
+ themeMode,
5630
+ light: light.tokens,
5631
+ dark: dark.tokens,
5632
+ kinds: primaryKinds,
5633
+ tokenCount: (/* @__PURE__ */ new Set([...Object.keys(light.tokens), ...Object.keys(dark.tokens)])).size
5634
+ };
5635
+ }
5636
+ function orderedEntries(tokens) {
5637
+ const names = Object.keys(tokens);
5638
+ const rank = (n) => {
5639
+ const i = SEMANTIC_ORDER.indexOf(n);
5640
+ return i === -1 ? SEMANTIC_ORDER.length : i;
5641
+ };
5642
+ return names.sort((a, b) => rank(a) - rank(b) || a.localeCompare(b)).map((n) => [n, tokens[n]]);
5643
+ }
5644
+ function renderBlock(selector, tokens) {
5645
+ const lines = orderedEntries(tokens).map(([n, v]) => ` --${n}: ${v};`);
5646
+ return `${selector} {
5647
+ ${lines.join("\n")}
5648
+ }`;
5649
+ }
5650
+ function formatExtraction(result) {
5651
+ if (result.themeMode === "none") {
5652
+ return [
5653
+ "# No design tokens found",
5654
+ "",
5655
+ "Could not find any CSS custom properties (`--name: value;`) in a `:root`, `.dark`, or `@theme` block.",
5656
+ "Paste the contents of the project's `globals.css` (or wherever the design tokens live) as the `css` argument."
5657
+ ].join("\n");
5658
+ }
5659
+ const base = Object.keys(result.light).length > 0 ? result.light : result.dark;
5660
+ const pick = (n) => base[n];
5661
+ const swatch = (label, n) => {
5662
+ const v = pick(n);
5663
+ return v ? `- **${label}** (\`--${n}\`): \`${v}\`` : null;
5664
+ };
5665
+ const palette = [
5666
+ swatch("Primary", "primary"),
5667
+ swatch("Background", "background"),
5668
+ swatch("Foreground", "foreground"),
5669
+ swatch("Accent", "accent"),
5670
+ swatch("Secondary", "secondary"),
5671
+ swatch("Border", "border"),
5672
+ swatch("Ring", "ring"),
5673
+ swatch("Destructive", "destructive")
5674
+ ].filter(Boolean);
5675
+ const radius = pick("radius");
5676
+ const fontSans = pick("font-sans");
5677
+ const fontMono = pick("font-mono");
5678
+ const shadowCount = Object.values(result.kinds).filter((k) => k === "shadow").length;
5679
+ const modeLabel = {
5680
+ light: "single light theme",
5681
+ dark: "single dark theme",
5682
+ dual: "light + dark themes",
5683
+ none: "none"
5684
+ };
5685
+ const meta = [
5686
+ result.name ? `**Source:** ${result.name}` : null,
5687
+ `**Theme:** ${modeLabel[result.themeMode]}`,
5688
+ `**Tokens extracted:** ${result.tokenCount}`,
5689
+ `**Colors normalized to oklch.**`
5690
+ ].filter(Boolean);
5691
+ const blocks = [];
5692
+ if (Object.keys(result.light).length > 0) {
5693
+ blocks.push(renderBlock(":root", result.light));
5694
+ }
5695
+ if (Object.keys(result.dark).length > 0) {
5696
+ blocks.push(renderBlock(".dark", result.dark));
5697
+ }
5698
+ const details = [];
5699
+ if (radius) details.push(`- **Radius:** \`${radius}\``);
5700
+ if (fontSans) details.push(`- **Font (sans):** \`${fontSans}\``);
5701
+ if (fontMono) details.push(`- **Font (mono):** \`${fontMono}\``);
5702
+ if (shadowCount > 0) details.push(`- **Shadow scale:** ${shadowCount} token${shadowCount === 1 ? "" : "s"}`);
5703
+ const sections = [
5704
+ `# Extracted design system${result.name ? `: ${result.name}` : ""}`,
5705
+ meta.join(" \n"),
5706
+ "## Palette\n" + (palette.length ? palette.join("\n") : "_No semantic color tokens recognized; see the full token sheet below._")
5707
+ ];
5708
+ if (details.length) {
5709
+ sections.push("## Type, radius & depth\n" + details.join("\n"));
5710
+ }
5711
+ sections.push(
5712
+ "## Token sheet (oklch-normalized, paste into globals.css)\n\n```css\n" + blocks.join("\n\n") + "\n```",
5713
+ "## How to use\n- Style new components against these tokens (`bg-background`, `text-foreground`, `bg-primary`, `border-border`, `ring-ring`) so they match the existing app.\n- To turn this into a full Better Design system, pass the palette to `create-design-system` as the brand description."
5714
+ );
5715
+ return sections.join("\n\n");
5716
+ }
5717
+ var SEMANTIC_ORDER;
5718
+ var init_extract_design_system = __esm({
5719
+ "../shared/src/mcp/extract-design-system.ts"() {
5720
+ "use strict";
5721
+ init_registry_css();
5722
+ init_color_to_oklch();
5723
+ SEMANTIC_ORDER = [
5724
+ "background",
5725
+ "foreground",
5726
+ "card",
5727
+ "card-foreground",
5728
+ "popover",
5729
+ "popover-foreground",
5730
+ "primary",
5731
+ "primary-foreground",
5732
+ "secondary",
5733
+ "secondary-foreground",
5734
+ "muted",
5735
+ "muted-foreground",
5736
+ "accent",
5737
+ "accent-foreground",
5738
+ "destructive",
5739
+ "destructive-foreground",
5740
+ "border",
5741
+ "input",
5742
+ "ring",
5743
+ "chart-1",
5744
+ "chart-2",
5745
+ "chart-3",
5746
+ "chart-4",
5747
+ "chart-5",
5748
+ "sidebar",
5749
+ "sidebar-foreground",
5750
+ "sidebar-primary",
5751
+ "sidebar-primary-foreground",
5752
+ "sidebar-accent",
5753
+ "sidebar-accent-foreground",
5754
+ "sidebar-border",
5755
+ "sidebar-ring",
5756
+ "radius",
5757
+ "font-sans",
5758
+ "font-serif",
5759
+ "font-mono"
5760
+ ];
5761
+ }
5762
+ });
5763
+
5764
+ // ../shared/src/mcp/tools/extract-tools.ts
5765
+ import { z as z5 } from "zod";
5766
+ function registerExtractTools({ server, tracked }) {
5767
+ server.registerTool(
5768
+ "extract-design-system",
5769
+ {
5770
+ title: "Extract Design System From Existing Code",
5771
+ description: `Distill the design tokens out of a project's EXISTING CSS so new components match the app the user already built.
5772
+
5773
+ Use this when the user says "match our existing style", "use our design system", "style this like the rest of the app", or you are adding UI to a codebase that already has its own look. This is the inverse of find-design-system / create-design-system: instead of giving the user one of our systems, it reads theirs.
5774
+
5775
+ How to use it: read the project's \`globals.css\` (or wherever the design tokens / CSS custom properties live, e.g. a Tailwind v4 \`@theme\` block) and pass its full contents as \`css\`. The MCP server cannot read your filesystem, so you must paste the text.
5776
+
5777
+ Returns: the semantic palette (primary, background, foreground, accent, border, ring, etc.), radius, fonts, and shadow scale, plus a pasteable token sheet with every color normalized to \`oklch()\`. Handles hex, rgb()/rgba(), hsl()/hsla(), named colors, and existing oklch values, across \`:root\`, \`.dark\`, and \`@theme\` blocks.`,
5778
+ inputSchema: z5.object({
5779
+ css: z5.string().trim().min(1).max(2e5).describe("Full contents of the project's globals.css (or any CSS holding the design tokens / CSS custom properties)."),
5780
+ name: z5.string().trim().min(1).max(120).optional().describe("Optional label for the extracted system, e.g. the app or repo name."),
5781
+ maxTokens: z5.number().min(500).max(5e4).optional().describe("Maximum tokens to return. Truncates the token sheet to fit.")
5782
+ }),
5783
+ annotations: { readOnlyHint: true }
5784
+ },
5785
+ async ({ css, name, maxTokens }) => tracked("extract-design-system", { name: name ?? null }, async () => {
5786
+ const result = extractDesignSystem(css, name);
5787
+ let text = formatExtraction(result);
5788
+ if (maxTokens) text = truncateToTokens(text, maxTokens);
5789
+ return { content: [{ type: "text", text }] };
5790
+ })
5791
+ );
5792
+ }
5793
+ var init_extract_tools = __esm({
5794
+ "../shared/src/mcp/tools/extract-tools.ts"() {
5795
+ "use strict";
5796
+ init_shared();
5797
+ init_extract_design_system();
3618
5798
  }
3619
5799
  });
3620
5800
 
@@ -3672,6 +5852,7 @@ function registerAllTools(server, provider, onToolUsage, authContext) {
3672
5852
  registerPrincipleTools(deps);
3673
5853
  registerIconTools(deps);
3674
5854
  registerDesignSystemTools(deps);
5855
+ registerExtractTools(deps);
3675
5856
  registerPreviewResource(deps);
3676
5857
  }
3677
5858
  var init_tools = __esm({
@@ -3681,6 +5862,7 @@ var init_tools = __esm({
3681
5862
  init_principle_tools();
3682
5863
  init_icon_tools();
3683
5864
  init_design_system_tools();
5865
+ init_extract_tools();
3684
5866
  init_preview_resource();
3685
5867
  init_shared();
3686
5868
  }
@@ -3689,6 +5871,7 @@ var init_tools = __esm({
3689
5871
  // ../shared/src/mcp/index.ts
3690
5872
  var mcp_exports = {};
3691
5873
  __export(mcp_exports, {
5874
+ BUILD_TARGET_RULE: () => BUILD_TARGET_RULE,
3692
5875
  INSTRUCTIONS: () => INSTRUCTIONS,
3693
5876
  SEARCH_TOOLS: () => SEARCH_TOOLS,
3694
5877
  createMcpServer: () => createMcpServer
@@ -3716,6 +5899,7 @@ var init_mcp = __esm({
3716
5899
  init_tools();
3717
5900
  init_tools();
3718
5901
  init_instructions();
5902
+ init_shared();
3719
5903
  }
3720
5904
  });
3721
5905
 
@@ -3735,14 +5919,14 @@ __export(api_client_exports, {
3735
5919
  trackToolUsage: () => trackToolUsage
3736
5920
  });
3737
5921
  import { createHash as createHash2 } from "crypto";
3738
- async function request(path4) {
5922
+ async function request(path5) {
3739
5923
  if (!API_KEY) {
3740
5924
  throw new ApiError(
3741
5925
  401,
3742
5926
  "BETTER_DESIGN_API_KEY is not set. Run `npx better-design` to create a free key (no account needed), or get one at https://better-design.com/mcp"
3743
5927
  );
3744
5928
  }
3745
- const res = await fetch(`${API_URL2}/api${path4}`, {
5929
+ const res = await fetch(`${API_URL2}/api${path5}`, {
3746
5930
  headers: {
3747
5931
  Authorization: `Bearer ${API_KEY}`,
3748
5932
  "Content-Type": "application/json"
@@ -3923,6 +6107,68 @@ var init_http_data_provider = __esm({
3923
6107
  }
3924
6108
  });
3925
6109
 
6110
+ // src/lib/install-marker.ts
6111
+ var install_marker_exports = {};
6112
+ __export(install_marker_exports, {
6113
+ isFirstConnect: () => isFirstConnect
6114
+ });
6115
+ import { closeSync, mkdirSync as mkdirSync2, openSync, writeSync } from "fs";
6116
+ import os4 from "os";
6117
+ import path4 from "path";
6118
+ function slug(clientName) {
6119
+ const base = (clientName ?? "unknown").toLowerCase();
6120
+ const cleaned = base.replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
6121
+ return cleaned || "unknown";
6122
+ }
6123
+ function isFirstConnect(clientName) {
6124
+ try {
6125
+ mkdirSync2(MARKER_DIR, { recursive: true });
6126
+ const marker = path4.join(MARKER_DIR, slug(clientName));
6127
+ const fd = openSync(marker, "wx", 420);
6128
+ try {
6129
+ writeSync(fd, (/* @__PURE__ */ new Date()).toISOString());
6130
+ } finally {
6131
+ closeSync(fd);
6132
+ }
6133
+ return true;
6134
+ } catch {
6135
+ return false;
6136
+ }
6137
+ }
6138
+ var MARKER_DIR;
6139
+ var init_install_marker = __esm({
6140
+ "src/lib/install-marker.ts"() {
6141
+ "use strict";
6142
+ MARKER_DIR = path4.join(os4.homedir(), ".better-design", "connected");
6143
+ }
6144
+ });
6145
+
6146
+ // ../shared/src/mcp-debug-log.ts
6147
+ var mcp_debug_log_exports = {};
6148
+ __export(mcp_debug_log_exports, {
6149
+ mcpDebugLog: () => mcpDebugLog,
6150
+ mcpDebugLogPath: () => mcpDebugLogPath
6151
+ });
6152
+ function mcpDebugLogPath() {
6153
+ try {
6154
+ return typeof process !== "undefined" ? process.env?.MCP_DEBUG_LOG : void 0;
6155
+ } catch {
6156
+ return void 0;
6157
+ }
6158
+ }
6159
+ function mcpDebugLog(entry) {
6160
+ const path5 = mcpDebugLogPath();
6161
+ if (!path5) return Promise.resolve();
6162
+ return import("fs").then((fs) => fs.appendFileSync(path5, `${JSON.stringify(entry)}
6163
+ `)).catch(() => {
6164
+ });
6165
+ }
6166
+ var init_mcp_debug_log = __esm({
6167
+ "../shared/src/mcp-debug-log.ts"() {
6168
+ "use strict";
6169
+ }
6170
+ });
6171
+
3926
6172
  // src/index.ts
3927
6173
  var argv = process.argv.slice(2);
3928
6174
  var command = argv[0];
@@ -3943,16 +6189,34 @@ async function startServer() {
3943
6189
  const { createMcpServer: createMcpServer2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
3944
6190
  const { createHttpDataProvider: createHttpDataProvider2 } = await Promise.resolve().then(() => (init_http_data_provider(), http_data_provider_exports));
3945
6191
  const { trackToolUsage: trackToolUsage2, trackMcpInstalled: trackMcpInstalled2 } = await Promise.resolve().then(() => (init_api_client(), api_client_exports));
6192
+ const { isFirstConnect: isFirstConnect2 } = await Promise.resolve().then(() => (init_install_marker(), install_marker_exports));
6193
+ const { mcpDebugLog: mcpDebugLog2 } = await Promise.resolve().then(() => (init_mcp_debug_log(), mcp_debug_log_exports));
3946
6194
  const server = createMcpServer2({
3947
6195
  provider: createHttpDataProvider2(),
3948
6196
  name: "DesignSystems",
3949
6197
  version: "3.0.0",
3950
- onToolUsage: trackToolUsage2
6198
+ onToolUsage: (tool, params, ctx) => {
6199
+ mcpDebugLog2({
6200
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
6201
+ transport: "stdio",
6202
+ tool,
6203
+ args: params,
6204
+ durationMs: ctx.durationMs ?? null,
6205
+ status: ctx.isError ? "error" : "ok",
6206
+ errorMessage: ctx.errorMessage,
6207
+ outputPreview: ctx.outputPreview ?? null,
6208
+ clientName: ctx.clientName ?? null,
6209
+ clientVersion: ctx.clientVersion ?? null
6210
+ });
6211
+ trackToolUsage2(tool, params, ctx);
6212
+ }
3951
6213
  });
3952
6214
  server.server.oninitialized = () => {
3953
6215
  try {
3954
6216
  const info = server.server.getClientVersion?.();
3955
- trackMcpInstalled2({ clientName: info?.name, clientVersion: info?.version });
6217
+ if (isFirstConnect2(info?.name)) {
6218
+ trackMcpInstalled2({ clientName: info?.name, clientVersion: info?.version });
6219
+ }
3956
6220
  } catch {
3957
6221
  }
3958
6222
  };