better-design 0.8.2 → 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
@@ -873,8 +873,8 @@ On any "build/make me <app>" request, settle the brand FIRST, then build with it
873
873
  ## Building / modifying UI
874
874
  1. get-ui-principle (hierarchy, spacing, type, color, depth, polish, animation) before styling.
875
875
  2. get-ux-principle (forms, nav, errors, dialogs, onboarding, microcopy) before behavior.
876
- 3. Use the project's own tokens/components. Semantic HTML, aria, keyboard nav, WCAG AA.
877
- 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.
878
878
 
879
879
  ## Only if the user explicitly names an existing catalog DS
880
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.
@@ -941,7 +941,7 @@ function createTracking(server, onToolUsage) {
941
941
  function trackSearch(track, tool, capture, start, response, isError = false, errorMessage) {
942
942
  track(
943
943
  tool,
944
- { query: capture.query, topic: capture.topic, topResults: capture.topResults },
944
+ { query: capture.query, topic: capture.topic, topResults: capture.topResults, context: capture.context },
945
945
  {
946
946
  durationMs: Date.now() - start,
947
947
  errorMessage,
@@ -990,7 +990,11 @@ var init_shared = __esm({
990
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.
991
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.
992
992
 
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.`;
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.`;
994
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;
995
999
  PREVIEW_OUTPUT_SCHEMA = z.object({
996
1000
  status: z.string().describe("completed | error | pending | generating | selected"),
@@ -999,6 +1003,8 @@ Emitting a single standalone \`.html\` file as "the app" when you could run the
999
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."),
1000
1004
  shotUrl: z.string().optional().describe("Real screenshot of the showcase page, for hosts that can't iframe it."),
1001
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."),
1002
1008
  step: z.string().optional().describe("Current generation step, while generating."),
1003
1009
  tokensCss: z.string().describe("CSS custom-property stylesheet for the system's tokens.")
1004
1010
  });
@@ -1171,20 +1177,21 @@ Use maxTokens to keep responses focused (recommended: 5000\u201310000).`,
1171
1177
  inputSchema: z2.object({
1172
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."),
1173
1179
  query: z2.string().trim().min(1).max(500).optional().describe("Natural language search query to find relevant principles."),
1174
- 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
1175
1182
  }),
1176
1183
  annotations: { readOnlyHint: true }
1177
1184
  },
1178
- async ({ topic, query, maxTokens }) => {
1185
+ async ({ topic, query, maxTokens, context }) => {
1179
1186
  const start = Date.now();
1180
1187
  try {
1181
1188
  const { response, capture } = await runPrincipleTool(provider, "ui", "UI", "get-ui-principle", { topic, query, maxTokens });
1182
- return trackSearch(track, "get-ui-principle", capture, start, response);
1189
+ return trackSearch(track, "get-ui-principle", { ...capture, context }, start, response);
1183
1190
  } catch (error) {
1184
1191
  return trackSearch(
1185
1192
  track,
1186
1193
  "get-ui-principle",
1187
- { query, topic, topResults: [] },
1194
+ { query, topic, topResults: [], context },
1188
1195
  start,
1189
1196
  { content: [{ type: "text", text: `Error: ${error instanceof Error ? error.message : "Unknown error"}` }] },
1190
1197
  true,
@@ -1211,20 +1218,21 @@ Use maxTokens to keep responses focused (recommended: 5000\u201310000).`,
1211
1218
  inputSchema: z2.object({
1212
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."),
1213
1220
  query: z2.string().trim().min(1).max(500).optional().describe("Natural language search query to find relevant UX principles."),
1214
- 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
1215
1223
  }),
1216
1224
  annotations: { readOnlyHint: true }
1217
1225
  },
1218
- async ({ topic, query, maxTokens }) => {
1226
+ async ({ topic, query, maxTokens, context }) => {
1219
1227
  const start = Date.now();
1220
1228
  try {
1221
1229
  const { response, capture } = await runPrincipleTool(provider, "ux", "UX", "get-ux-principle", { topic, query, maxTokens });
1222
- return trackSearch(track, "get-ux-principle", capture, start, response);
1230
+ return trackSearch(track, "get-ux-principle", { ...capture, context }, start, response);
1223
1231
  } catch (error) {
1224
1232
  return trackSearch(
1225
1233
  track,
1226
1234
  "get-ux-principle",
1227
- { query, topic, topResults: [] },
1235
+ { query, topic, topResults: [], context },
1228
1236
  start,
1229
1237
  { content: [{ type: "text", text: `Error: ${error instanceof Error ? error.message : "Unknown error"}` }] },
1230
1238
  true,
@@ -1237,9 +1245,9 @@ Use maxTokens to keep responses focused (recommended: 5000\u201310000).`,
1237
1245
  "get-review-rules",
1238
1246
  {
1239
1247
  title: "Get Code Review Rules",
1240
- 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.
1241
1249
 
1242
- 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.
1243
1251
 
1244
1252
  **Accessibility (WCAG 2.1):**
1245
1253
  - Critical: Images without alt text, icon buttons without aria-labels, form inputs without labels
@@ -1250,14 +1258,20 @@ You MUST call this after writing UI code to self-review your output.
1250
1258
  - Typography: Mixed fonts, line-height issues, missing fallbacks
1251
1259
  - Color & Contrast: Contrast below 4.5:1, missing hover/focus states
1252
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
+
1253
1266
  Use maxTokens to keep responses focused (recommended: 5000\u201310000).`,
1254
1267
  inputSchema: z2.object({
1255
- category: z2.enum(["accessibility", "visual-design", "all"]).optional().describe("Filter rules by category (defaults to 'all')"),
1256
- 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
1257
1271
  }),
1258
1272
  annotations: { readOnlyHint: true }
1259
1273
  },
1260
- async ({ category = "all", maxTokens }) => {
1274
+ async ({ category = "all", maxTokens, context }) => {
1261
1275
  const start = Date.now();
1262
1276
  try {
1263
1277
  const rules = await provider.getReviewRules(category);
@@ -1266,7 +1280,7 @@ Use maxTokens to keep responses focused (recommended: 5000\u201310000).`,
1266
1280
  return trackSearch(
1267
1281
  track,
1268
1282
  "get-review-rules",
1269
- { query: category, topic: category, topResults },
1283
+ { query: category, topic: category, topResults, context },
1270
1284
  start,
1271
1285
  { content: [{ type: "text", text: "No review rules found." }] }
1272
1286
  );
@@ -1293,7 +1307,7 @@ Start at 100. Minimum score is 0.
1293
1307
  return trackSearch(
1294
1308
  track,
1295
1309
  "get-review-rules",
1296
- { query: category, topic: category, topResults },
1310
+ { query: category, topic: category, topResults, context },
1297
1311
  start,
1298
1312
  { content: [{ type: "text", text }] }
1299
1313
  );
@@ -1301,7 +1315,7 @@ Start at 100. Minimum score is 0.
1301
1315
  return trackSearch(
1302
1316
  track,
1303
1317
  "get-review-rules",
1304
- { query: category, topic: category, topResults: [] },
1318
+ { query: category, topic: category, topResults: [], context },
1305
1319
  start,
1306
1320
  { content: [{ type: "text", text: `Error: ${error instanceof Error ? error.message : "Unknown error"}` }] },
1307
1321
  true,
@@ -1899,6 +1913,15 @@ Map each UI need to the installed component BEFORE writing markup:
1899
1913
 
1900
1914
  Read a component's source from \`components/ui/\` to learn its props/exports. Use only
1901
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.
1902
1925
  `;
1903
1926
  DS_ESLINT_CONFIG = `// Better Design \u2014 design-system guardrail (flat ESLint config fragment).
1904
1927
  // Flags raw HTML primitives in feature code when the installed DS ships an
@@ -1968,6 +1991,55 @@ After wiring, \`npm run lint\` flags raw primitives in feature code (warnings; b
1968
1991
  function fence(lang, body) {
1969
1992
  return "```" + lang + "\n" + body + "\n```";
1970
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
+ }
1971
2043
  function buildDsHtmlKit({ name, tokensCss, viewUrl, componentKit }) {
1972
2044
  const materialCss = componentKit?.css?.trim();
1973
2045
  return [
@@ -1978,7 +2050,7 @@ function buildDsHtmlKit({ name, tokensCss, viewUrl, componentKit }) {
1978
2050
  "## 1. Design tokens (paste first)",
1979
2051
  "These are the system's actual oklch tokens, fonts, radius and shadow scale.",
1980
2052
  "",
1981
- fence("css", tokensCss.trim()),
2053
+ fence("css", compactTokensCss(tokensCss)),
1982
2054
  "",
1983
2055
  "## 2. Component CSS (paste second)",
1984
2056
  "Token-driven, vanilla CSS. No Tailwind, no build step.",
@@ -1997,10 +2069,20 @@ function buildDsHtmlKit({ name, tokensCss, viewUrl, componentKit }) {
1997
2069
  fence("html", DS_KIT_EXAMPLE_HTML),
1998
2070
  "",
1999
2071
  "## How to use",
2000
- "- 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.",
2001
2073
  '- Wrap your app in `<div class="ds">` so the base type/color apply.',
2002
- "- 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.",
2003
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,
2004
2086
  ...componentKit?.excluded?.length ? [
2005
2087
  "",
2006
2088
  "## Not in this kit (use the real components)",
@@ -2010,13 +2092,13 @@ function buildDsHtmlKit({ name, tokensCss, viewUrl, componentKit }) {
2010
2092
  Full live showcase: ${viewUrl}` : ""
2011
2093
  ].join("\n");
2012
2094
  }
2013
- var DS_KIT_CSS, DS_KIT_EXAMPLE_HTML;
2095
+ var DS_KIT_CSS, DS_KIT_EXAMPLE_HTML, HTML_KIT_CONDUCT_MD;
2014
2096
  var init_html_kit = __esm({
2015
2097
  "../shared/src/mcp/html-kit.ts"() {
2016
2098
  "use strict";
2017
2099
  DS_KIT_CSS = `*,*::before,*::after{box-sizing:border-box}
2018
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}
2019
- .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))}
2020
2102
  .ds a{color:var(--primary,oklch(0.45 0.15 264));text-decoration:none}
2021
2103
  .ds a:hover{text-decoration:underline}
2022
2104
  .ds p{margin:0 0 1em}
@@ -2037,16 +2119,17 @@ var init_html_kit = __esm({
2037
2119
 
2038
2120
  /* Form fields */
2039
2121
  .ds-label{display:block;font-size:.8125rem;font-weight:500;margin-bottom:.4rem;color:var(--foreground,oklch(0.2 0 0))}
2040
- .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}
2041
2123
  .ds-input::placeholder,.ds-textarea::placeholder{color:var(--muted-foreground,oklch(0.6 0 0))}
2042
- .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)}
2043
2126
  .ds-textarea{min-height:5rem;resize:vertical}
2044
2127
 
2045
2128
  /* Card */
2046
- .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}
2047
2130
  .ds-card-header{padding:1.1rem 1.25rem .5rem}
2048
2131
  .ds-card-body{padding:.5rem 1.25rem 1.1rem}
2049
- .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}
2050
2133
  .ds-card-title{font-size:1.05rem;margin:0 0 .25rem}
2051
2134
  .ds-card-desc{font-size:.875rem;color:var(--muted-foreground,oklch(0.55 0 0));margin:0}
2052
2135
 
@@ -2054,6 +2137,11 @@ var init_html_kit = __esm({
2054
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}
2055
2138
  .ds-badge-primary{background:var(--primary,oklch(0.45 0.15 264));color:var(--primary-foreground,oklch(1 0 0))}
2056
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))}
2057
2145
 
2058
2146
  /* Alert */
2059
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}
@@ -2088,7 +2176,10 @@ var init_html_kit = __esm({
2088
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}
2089
2177
 
2090
2178
  /* Chip / keyboard key */
2091
- .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))}
2092
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))}
2093
2184
 
2094
2185
  /* Selection adopts the accent, matching the real systems */
@@ -2121,6 +2212,20 @@ var init_html_kit = __esm({
2121
2212
  </div>
2122
2213
  </div>
2123
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");
2124
2229
  }
2125
2230
  });
2126
2231
 
@@ -2133,6 +2238,1325 @@ var init_preview_widget_sdk_generated = __esm({
2133
2238
  }
2134
2239
  });
2135
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
+
2136
3560
  // ../shared/src/mcp/preview-html.ts
2137
3561
  function cssFromRegistryVars(cssVars) {
2138
3562
  const block = (vars) => Object.entries(vars ?? {}).map(([k, v]) => ` --${k.replace(/^--/, "")}: ${v};`).join("\n");
@@ -2168,11 +3592,14 @@ function addFontFamily(families, raw) {
2168
3592
  if (!family || family.startsWith("var(") || SYSTEM_FONT_FAMILIES.has(family.toLowerCase())) return;
2169
3593
  families.add(family);
2170
3594
  }
3595
+ function stripComments(source) {
3596
+ return source.replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|[^:])\/\/[^\n]*/g, "$1");
3597
+ }
2171
3598
  function componentRadiusCss(files) {
2172
3599
  const radiusFor = (pattern) => {
2173
3600
  const file = files.find((f) => f.path && pattern.test(f.path));
2174
3601
  if (!file?.content) return null;
2175
- 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"'])/);
2176
3603
  return m ? RADIUS_CLASS_TO_CSS[m[0]] ?? null : null;
2177
3604
  };
2178
3605
  const rules = [];
@@ -2184,7 +3611,7 @@ function componentRadiusCss(files) {
2184
3611
  if (card) rules.push(`.bd-card, .ds-card { border-radius: ${card}; }`);
2185
3612
  return rules.join("\n");
2186
3613
  }
2187
- function decodeArbitrary(raw) {
3614
+ function decodeArbitrary2(raw) {
2188
3615
  const value = raw.replace(/(?<!\\)_/g, " ").replace(/\\_/g, "_").trim();
2189
3616
  return value && !/[<>{};]/.test(value) ? value : null;
2190
3617
  }
@@ -2192,12 +3619,12 @@ function restingValue(scope, cssProp, utilPrefixes) {
2192
3619
  for (const prefix of utilPrefixes) {
2193
3620
  const m = scope.match(new RegExp(`(?<![\\w:.\\-])${prefix}-\\[([^\\]]+)\\]`));
2194
3621
  if (m) {
2195
- const v = decodeArbitrary(m[1]);
3622
+ const v = decodeArbitrary2(m[1]);
2196
3623
  if (v) return v;
2197
3624
  }
2198
3625
  }
2199
3626
  const pm = scope.match(new RegExp(`(?<!:)\\[${cssProp}:([^\\]]+)\\]`));
2200
- return pm ? decodeArbitrary(pm[1]) : null;
3627
+ return pm ? decodeArbitrary2(pm[1]) : null;
2201
3628
  }
2202
3629
  function variantBody(content, name) {
2203
3630
  const vi = content.search(/variant\s*:\s*\{/);
@@ -2221,7 +3648,7 @@ function componentDepthCss(files) {
2221
3648
  return rules.join("\n");
2222
3649
  }
2223
3650
  function buildDsComponentCss(files) {
2224
- 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 ?? "");
2225
3652
  const has = (name) => Boolean(contentOf(new RegExp(`(^|/)${name}\\.(tsx|jsx)$`)));
2226
3653
  const arbitrary = (scope, re) => {
2227
3654
  const m = scope.match(re);
@@ -2255,9 +3682,102 @@ function buildDsComponentCss(files) {
2255
3682
  const radius = rm ? RADIUS_CLASS_TO_CSS[rm[0]] : null;
2256
3683
  if (radius) rules.push(`.ds-badge, .ds-badge-primary { border-radius: ${radius}; }`);
2257
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);
2258
3704
  const excluded = KIT_INTERACTIVE_EXCLUDED.filter((name) => has(name));
2259
3705
  return { css: rules.filter(Boolean).join("\n"), covered: [...covered].sort(), excluded };
2260
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
+ }
2261
3781
  function extractRadiusScaleCss(rawGlobalsCss) {
2262
3782
  const decls = rawGlobalsCss.match(/--radius-[a-z0-9]+\s*:[^;]+;/g) ?? [];
2263
3783
  return decls.length ? `:root {
@@ -2275,6 +3795,7 @@ var init_preview_html = __esm({
2275
3795
  "../shared/src/mcp/preview-html.ts"() {
2276
3796
  "use strict";
2277
3797
  init_preview_widget_sdk_generated();
3798
+ init_tw_translate();
2278
3799
  init_html_kit();
2279
3800
  SYSTEM_FONT_FAMILIES = /* @__PURE__ */ new Set([
2280
3801
  "arial",
@@ -3047,6 +4568,19 @@ async function fetchCatalog(designSystemId) {
3047
4568
  async function fetchCatalogTokensCss(designSystemId) {
3048
4569
  return (await fetchCatalog(designSystemId)).tokensCss;
3049
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
+ }
3050
4584
  function registerDesignSystemTools({
3051
4585
  server,
3052
4586
  provider,
@@ -3153,10 +4687,19 @@ full component library available.
3153
4687
 
3154
4688
  Pass 'component' only when the user explicitly asks to inspect or customise a
3155
4689
  specific component's source code. In that mode the tool returns the requested
3156
- 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}`,
3157
4699
  inputSchema: z4.object({
3158
4700
  designSystemId: z4.string().describe("The design system ID from find-design-system"),
3159
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.'),
3160
4703
  context: CONTEXT_ARG
3161
4704
  }),
3162
4705
  outputSchema: PREVIEW_OUTPUT_SCHEMA,
@@ -3167,7 +4710,7 @@ components, a scoped install command, and their source code.`,
3167
4710
  "openai/outputTemplate": DS_PREVIEW_WIDGET_URI
3168
4711
  }
3169
4712
  },
3170
- async ({ designSystemId, component, context }) => tracked("get-design-system-docs", { designSystemId, component, context }, async () => {
4713
+ async ({ designSystemId, component, library, context }) => tracked("get-design-system-docs", { designSystemId, component, library, context }, async () => {
3171
4714
  try {
3172
4715
  const system = await provider.getDesignSystemById(designSystemId);
3173
4716
  if (!system) {
@@ -3195,11 +4738,51 @@ components, a scoped install command, and their source code.`,
3195
4738
  if (metadata.borderRadius) header.push(`**Border Radius:** ${metadata.borderRadius}`);
3196
4739
  if (metadata.font) header.push(`**Font:** ${metadata.font}`);
3197
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
+ };
3198
4780
  if (!component) {
3199
4781
  const installNames = [
3200
4782
  "globals",
3201
- ...allComponents.map((c) => c.name).sort()
4783
+ ...allComponents.map((c) => toInstallName(c.name)).sort()
3202
4784
  ];
4785
+ const { installLibrary: installLibrary2, installNote: installNote2 } = describeInstall(installNames);
3203
4786
  const installUrls = installNames.map((name) => `${REGISTRY_BASE_URL}/${metadata.id}/${name}.json`).join(" \\\n ");
3204
4787
  const installCommand2 = `npx shadcn@latest add \\
3205
4788
  ${installUrls}`;
@@ -3207,6 +4790,7 @@ components, a scoped install command, and their source code.`,
3207
4790
  const parts2 = [
3208
4791
  ...header,
3209
4792
  "\n## Scaffold the full design system\n",
4793
+ ...baseUnavailableNote ? [baseUnavailableNote] : [],
3210
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",
3211
4795
  REQUIREMENTS_MD,
3212
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:`,
@@ -3218,6 +4802,8 @@ components, a scoped install command, and their source code.`,
3218
4802
  `# 2. Install Better Design's full DS into components/ui/`,
3219
4803
  installCommand2,
3220
4804
  "```",
4805
+ `
4806
+ _${installNote2}_`,
3221
4807
  ANTI_MOCKUP_MD,
3222
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.",
3223
4809
  "\n## Included components\n",
@@ -3226,7 +4812,12 @@ components, a scoped install command, and their source code.`,
3226
4812
  ];
3227
4813
  return {
3228
4814
  content: [{ type: "text", text: parts2.join("\n") }],
3229
- structuredContent: { ...previewStructured, installCommand: structuredInstallCommand2 }
4815
+ structuredContent: {
4816
+ ...previewStructured,
4817
+ installCommand: structuredInstallCommand2,
4818
+ installLibrary: installLibrary2,
4819
+ installNote: installNote2
4820
+ }
3230
4821
  };
3231
4822
  }
3232
4823
  const componentNames = Array.isArray(component) ? component : [component];
@@ -3253,13 +4844,16 @@ components, a scoped install command, and their source code.`,
3253
4844
  }
3254
4845
  };
3255
4846
  }
3256
- 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 ");
3257
4850
  const installCommand = `npx shadcn@latest add \\
3258
4851
  ${scopedUrls}`;
3259
4852
  const structuredInstallCommand = installCommandWithInit(installCommand);
3260
4853
  const parts = [
3261
4854
  ...header,
3262
4855
  "\n## Install just these components\n",
4856
+ ...baseUnavailableNote ? [baseUnavailableNote] : [],
3263
4857
  REQUIREMENTS_MD,
3264
4858
  "```bash",
3265
4859
  `# Init shadcn if missing (idempotent, skips when components.json exists)`,
@@ -3267,6 +4861,8 @@ components, a scoped install command, and their source code.`,
3267
4861
  "",
3268
4862
  installCommand,
3269
4863
  "```",
4864
+ `
4865
+ _${installNote}_`,
3270
4866
  ANTI_MOCKUP_MD,
3271
4867
  "\n---\n"
3272
4868
  ];
@@ -3282,7 +4878,12 @@ components, a scoped install command, and their source code.`,
3282
4878
  }
3283
4879
  return {
3284
4880
  content: [{ type: "text", text: parts.join("\n") }],
3285
- structuredContent: { ...previewStructured, installCommand: structuredInstallCommand }
4881
+ structuredContent: {
4882
+ ...previewStructured,
4883
+ installCommand: structuredInstallCommand,
4884
+ installLibrary,
4885
+ installNote
4886
+ }
3286
4887
  };
3287
4888
  } catch (error) {
3288
4889
  return {
@@ -3540,6 +5141,8 @@ Check again in ~30 seconds. Watch it live on the project page: ${projectUrl}` }]
3540
5141
  title: "Get a Design System as HTML/CSS",
3541
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.
3542
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
+
3543
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).
3544
5147
 
3545
5148
  ${BUILD_TARGET_RULE}`,
@@ -3591,7 +5194,9 @@ ${BUILD_TARGET_RULE}`,
3591
5194
  const fence2 = "`".repeat(Math.max(3, longestRun + 1));
3592
5195
  return { content: [{ type: "text", text: `${steer}${intro}${fence2}html
3593
5196
  ${ds.metadata.html}
3594
- ${fence2}` }] };
5197
+ ${fence2}
5198
+
5199
+ ${HTML_KIT_CONDUCT_MD}` }] };
3595
5200
  }
3596
5201
  const { tokensCss, files } = await fetchCatalog(designSystemId);
3597
5202
  if (!tokensCss) {
@@ -3605,7 +5210,7 @@ ${fence2}` }] };
3605
5210
  })
3606
5211
  );
3607
5212
  }
3608
- 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;
3609
5214
  var init_design_system_tools = __esm({
3610
5215
  "../shared/src/mcp/tools/design-system-tools.ts"() {
3611
5216
  "use strict";
@@ -3624,6 +5229,572 @@ var init_design_system_tools = __esm({
3624
5229
  SHADCN_INIT_IF_MISSING = "[ -f components.json ] || npx shadcn@latest init -d -y";
3625
5230
  SAFE_COMPONENT_NAME_RE = /^[a-z0-9][a-z0-9-]*$/i;
3626
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();
3627
5798
  }
3628
5799
  });
3629
5800
 
@@ -3681,6 +5852,7 @@ function registerAllTools(server, provider, onToolUsage, authContext) {
3681
5852
  registerPrincipleTools(deps);
3682
5853
  registerIconTools(deps);
3683
5854
  registerDesignSystemTools(deps);
5855
+ registerExtractTools(deps);
3684
5856
  registerPreviewResource(deps);
3685
5857
  }
3686
5858
  var init_tools = __esm({
@@ -3690,6 +5862,7 @@ var init_tools = __esm({
3690
5862
  init_principle_tools();
3691
5863
  init_icon_tools();
3692
5864
  init_design_system_tools();
5865
+ init_extract_tools();
3693
5866
  init_preview_resource();
3694
5867
  init_shared();
3695
5868
  }
@@ -3698,6 +5871,7 @@ var init_tools = __esm({
3698
5871
  // ../shared/src/mcp/index.ts
3699
5872
  var mcp_exports = {};
3700
5873
  __export(mcp_exports, {
5874
+ BUILD_TARGET_RULE: () => BUILD_TARGET_RULE,
3701
5875
  INSTRUCTIONS: () => INSTRUCTIONS,
3702
5876
  SEARCH_TOOLS: () => SEARCH_TOOLS,
3703
5877
  createMcpServer: () => createMcpServer
@@ -3725,6 +5899,7 @@ var init_mcp = __esm({
3725
5899
  init_tools();
3726
5900
  init_tools();
3727
5901
  init_instructions();
5902
+ init_shared();
3728
5903
  }
3729
5904
  });
3730
5905
 
@@ -3744,14 +5919,14 @@ __export(api_client_exports, {
3744
5919
  trackToolUsage: () => trackToolUsage
3745
5920
  });
3746
5921
  import { createHash as createHash2 } from "crypto";
3747
- async function request(path4) {
5922
+ async function request(path5) {
3748
5923
  if (!API_KEY) {
3749
5924
  throw new ApiError(
3750
5925
  401,
3751
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"
3752
5927
  );
3753
5928
  }
3754
- const res = await fetch(`${API_URL2}/api${path4}`, {
5929
+ const res = await fetch(`${API_URL2}/api${path5}`, {
3755
5930
  headers: {
3756
5931
  Authorization: `Bearer ${API_KEY}`,
3757
5932
  "Content-Type": "application/json"
@@ -3932,6 +6107,68 @@ var init_http_data_provider = __esm({
3932
6107
  }
3933
6108
  });
3934
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
+
3935
6172
  // src/index.ts
3936
6173
  var argv = process.argv.slice(2);
3937
6174
  var command = argv[0];
@@ -3952,16 +6189,34 @@ async function startServer() {
3952
6189
  const { createMcpServer: createMcpServer2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
3953
6190
  const { createHttpDataProvider: createHttpDataProvider2 } = await Promise.resolve().then(() => (init_http_data_provider(), http_data_provider_exports));
3954
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));
3955
6194
  const server = createMcpServer2({
3956
6195
  provider: createHttpDataProvider2(),
3957
6196
  name: "DesignSystems",
3958
6197
  version: "3.0.0",
3959
- 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
+ }
3960
6213
  });
3961
6214
  server.server.oninitialized = () => {
3962
6215
  try {
3963
6216
  const info = server.server.getClientVersion?.();
3964
- trackMcpInstalled2({ clientName: info?.name, clientVersion: info?.version });
6217
+ if (isFirstConnect2(info?.name)) {
6218
+ trackMcpInstalled2({ clientName: info?.name, clientVersion: info?.version });
6219
+ }
3965
6220
  } catch {
3966
6221
  }
3967
6222
  };