flowdoc-gen 0.1.5 → 0.1.6

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/bin.js CHANGED
@@ -13,11 +13,11 @@ program.command("init").description("Scaffold a flowdoc.config.ts in the current
13
13
  init();
14
14
  });
15
15
  program.command("generate").description("Parse your routes and write docs to the output folder").option("-c, --config <path>", "Path to flowdoc config file").option("-o, --output <path>", "Override output directory").option("-q, --quiet", "Suppress output").action(async (opts) => {
16
- const { generate } = await import("./generate-4NMSVNJF.js");
16
+ const { generate } = await import("./generate-TGEAHUE2.js");
17
17
  await generate(opts);
18
18
  });
19
19
  program.command("serve").description("Generate docs and serve them locally").option("-c, --config <path>", "Path to flowdoc config file").option("-o, --output <path>", "Override output directory").option("-p, --port <number>", "Port to serve on (default: 4000)", "4000").option("-w, --watch", "Re-generate docs on source file changes").option("--no-open", "Don't open browser automatically").action(async (opts) => {
20
- const { serve } = await import("./serve-AD6IWZXI.js");
20
+ const { serve } = await import("./serve-M5UPSOY5.js");
21
21
  const serveOpts = {
22
22
  port: opts.port ? parseInt(opts.port, 10) : 4e3,
23
23
  noOpen: !opts.open,
@@ -885,14 +885,23 @@ var tryExtractRoute = (call, ctx) => {
885
885
  const { requestBody, parameters } = extractFromMiddleware(middlewareArgs, ctx);
886
886
  const pathParams = extractPathParameters(path);
887
887
  const handlerInfo = extractHandlerInfo(handlerArg);
888
+ const responseSchemas = extractResponseSchemas(handlerArg);
888
889
  const allParameters = mergeParameters(parameters, pathParams);
889
890
  const tags = inferTags(path);
891
+ const responses = buildDefaultResponses(method);
892
+ for (const [code, schema] of Object.entries(responseSchemas)) {
893
+ const existing = responses[code] ?? { description: `HTTP ${code}` };
894
+ responses[code] = {
895
+ ...existing,
896
+ content: { "application/json": { schema } }
897
+ };
898
+ }
890
899
  const route = {
891
900
  method,
892
901
  path,
893
902
  tags,
894
903
  parameters: allParameters,
895
- responses: buildDefaultResponses(method),
904
+ responses,
896
905
  middleware: middlewareArgs.map((m) => m.getText())
897
906
  };
898
907
  if (handlerInfo.summary !== void 0) route.summary = handlerInfo.summary;
@@ -951,6 +960,64 @@ var extractPathParameters = (path) => {
951
960
  }
952
961
  return params;
953
962
  };
963
+ var extractResponseSchemas = (handler) => {
964
+ const result = {};
965
+ const calls = handler.getDescendantsOfKind(SyntaxKind3.CallExpression);
966
+ for (const call of calls) {
967
+ const expr = call.getExpression();
968
+ if (!Node5.isPropertyAccessExpression(expr)) continue;
969
+ const methodName = expr.getName();
970
+ if (methodName !== "json" && methodName !== "send") continue;
971
+ let statusCode = "200";
972
+ const callee = expr.getExpression();
973
+ if (Node5.isCallExpression(callee)) {
974
+ const statusExpr = callee.getExpression();
975
+ if (Node5.isPropertyAccessExpression(statusExpr) && statusExpr.getName() === "status") {
976
+ const statusArg = callee.getArguments()[0];
977
+ if (statusArg && Node5.isNumericLiteral(statusArg)) {
978
+ statusCode = statusArg.getText();
979
+ }
980
+ }
981
+ }
982
+ const args = call.getArguments();
983
+ if (args.length === 0) continue;
984
+ const arg = args[0];
985
+ if (!arg || !Node5.isObjectLiteralExpression(arg)) continue;
986
+ const schema = schemaFromObjectLiteral(arg);
987
+ if (schema && Object.keys(schema.properties ?? {}).length > 0) {
988
+ if (!result[statusCode]) result[statusCode] = schema;
989
+ }
990
+ }
991
+ return result;
992
+ };
993
+ var schemaFromObjectLiteral = (obj) => {
994
+ const properties = {};
995
+ for (const prop of obj.getProperties()) {
996
+ if (!Node5.isPropertyAssignment(prop)) continue;
997
+ const name = prop.getNameNode().getText().replace(/['"]/g, "");
998
+ const init = prop.getInitializer();
999
+ if (!init) continue;
1000
+ properties[name] = schemaFromValue(init);
1001
+ }
1002
+ return { type: "object", properties };
1003
+ };
1004
+ var schemaFromValue = (expr) => {
1005
+ if (Node5.isStringLiteral(expr) || Node5.isTemplateExpression(expr) || Node5.isNoSubstitutionTemplateLiteral(expr))
1006
+ return { type: "string", example: Node5.isStringLiteral(expr) ? expr.getLiteralValue() : void 0 };
1007
+ if (Node5.isNumericLiteral(expr))
1008
+ return { type: "number", example: Number(expr.getLiteralValue()) };
1009
+ if (expr.getKind() === SyntaxKind3.TrueKeyword || expr.getKind() === SyntaxKind3.FalseKeyword)
1010
+ return { type: "boolean", example: expr.getKind() === SyntaxKind3.TrueKeyword };
1011
+ if (Node5.isNullLiteral(expr))
1012
+ return { type: "null" };
1013
+ if (Node5.isArrayLiteralExpression(expr)) {
1014
+ const items = expr.getElements()[0];
1015
+ return { type: "array", items: items ? schemaFromValue(items) : {} };
1016
+ }
1017
+ if (Node5.isObjectLiteralExpression(expr))
1018
+ return schemaFromObjectLiteral(expr);
1019
+ return {};
1020
+ };
954
1021
  var extractHandlerInfo = (handler) => {
955
1022
  const leadingComments = handler.getLeadingCommentRanges();
956
1023
  if (leadingComments.length === 0) return {};
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  generate
3
- } from "./chunk-ZJCRRUX7.js";
3
+ } from "./chunk-KSXE5LV4.js";
4
4
  export {
5
5
  generate
6
6
  };
package/dist/index.cjs CHANGED
@@ -925,14 +925,23 @@ var tryExtractRoute = (call, ctx) => {
925
925
  const { requestBody, parameters } = extractFromMiddleware(middlewareArgs, ctx);
926
926
  const pathParams = extractPathParameters(path);
927
927
  const handlerInfo = extractHandlerInfo(handlerArg);
928
+ const responseSchemas = extractResponseSchemas(handlerArg);
928
929
  const allParameters = mergeParameters(parameters, pathParams);
929
930
  const tags = inferTags(path);
931
+ const responses = buildDefaultResponses(method);
932
+ for (const [code, schema] of Object.entries(responseSchemas)) {
933
+ const existing = responses[code] ?? { description: `HTTP ${code}` };
934
+ responses[code] = {
935
+ ...existing,
936
+ content: { "application/json": { schema } }
937
+ };
938
+ }
930
939
  const route = {
931
940
  method,
932
941
  path,
933
942
  tags,
934
943
  parameters: allParameters,
935
- responses: buildDefaultResponses(method),
944
+ responses,
936
945
  middleware: middlewareArgs.map((m) => m.getText())
937
946
  };
938
947
  if (handlerInfo.summary !== void 0) route.summary = handlerInfo.summary;
@@ -991,6 +1000,64 @@ var extractPathParameters = (path) => {
991
1000
  }
992
1001
  return params;
993
1002
  };
1003
+ var extractResponseSchemas = (handler) => {
1004
+ const result = {};
1005
+ const calls = handler.getDescendantsOfKind(import_ts_morph.SyntaxKind.CallExpression);
1006
+ for (const call of calls) {
1007
+ const expr = call.getExpression();
1008
+ if (!import_ts_morph.Node.isPropertyAccessExpression(expr)) continue;
1009
+ const methodName = expr.getName();
1010
+ if (methodName !== "json" && methodName !== "send") continue;
1011
+ let statusCode = "200";
1012
+ const callee = expr.getExpression();
1013
+ if (import_ts_morph.Node.isCallExpression(callee)) {
1014
+ const statusExpr = callee.getExpression();
1015
+ if (import_ts_morph.Node.isPropertyAccessExpression(statusExpr) && statusExpr.getName() === "status") {
1016
+ const statusArg = callee.getArguments()[0];
1017
+ if (statusArg && import_ts_morph.Node.isNumericLiteral(statusArg)) {
1018
+ statusCode = statusArg.getText();
1019
+ }
1020
+ }
1021
+ }
1022
+ const args = call.getArguments();
1023
+ if (args.length === 0) continue;
1024
+ const arg = args[0];
1025
+ if (!arg || !import_ts_morph.Node.isObjectLiteralExpression(arg)) continue;
1026
+ const schema = schemaFromObjectLiteral(arg);
1027
+ if (schema && Object.keys(schema.properties ?? {}).length > 0) {
1028
+ if (!result[statusCode]) result[statusCode] = schema;
1029
+ }
1030
+ }
1031
+ return result;
1032
+ };
1033
+ var schemaFromObjectLiteral = (obj) => {
1034
+ const properties = {};
1035
+ for (const prop of obj.getProperties()) {
1036
+ if (!import_ts_morph.Node.isPropertyAssignment(prop)) continue;
1037
+ const name = prop.getNameNode().getText().replace(/['"]/g, "");
1038
+ const init2 = prop.getInitializer();
1039
+ if (!init2) continue;
1040
+ properties[name] = schemaFromValue(init2);
1041
+ }
1042
+ return { type: "object", properties };
1043
+ };
1044
+ var schemaFromValue = (expr) => {
1045
+ if (import_ts_morph.Node.isStringLiteral(expr) || import_ts_morph.Node.isTemplateExpression(expr) || import_ts_morph.Node.isNoSubstitutionTemplateLiteral(expr))
1046
+ return { type: "string", example: import_ts_morph.Node.isStringLiteral(expr) ? expr.getLiteralValue() : void 0 };
1047
+ if (import_ts_morph.Node.isNumericLiteral(expr))
1048
+ return { type: "number", example: Number(expr.getLiteralValue()) };
1049
+ if (expr.getKind() === import_ts_morph.SyntaxKind.TrueKeyword || expr.getKind() === import_ts_morph.SyntaxKind.FalseKeyword)
1050
+ return { type: "boolean", example: expr.getKind() === import_ts_morph.SyntaxKind.TrueKeyword };
1051
+ if (import_ts_morph.Node.isNullLiteral(expr))
1052
+ return { type: "null" };
1053
+ if (import_ts_morph.Node.isArrayLiteralExpression(expr)) {
1054
+ const items = expr.getElements()[0];
1055
+ return { type: "array", items: items ? schemaFromValue(items) : {} };
1056
+ }
1057
+ if (import_ts_morph.Node.isObjectLiteralExpression(expr))
1058
+ return schemaFromObjectLiteral(expr);
1059
+ return {};
1060
+ };
994
1061
  var extractHandlerInfo = (handler) => {
995
1062
  const leadingComments = handler.getLeadingCommentRanges();
996
1063
  if (leadingComments.length === 0) return {};
package/dist/index.js CHANGED
@@ -885,14 +885,23 @@ var tryExtractRoute = (call, ctx) => {
885
885
  const { requestBody, parameters } = extractFromMiddleware(middlewareArgs, ctx);
886
886
  const pathParams = extractPathParameters(path);
887
887
  const handlerInfo = extractHandlerInfo(handlerArg);
888
+ const responseSchemas = extractResponseSchemas(handlerArg);
888
889
  const allParameters = mergeParameters(parameters, pathParams);
889
890
  const tags = inferTags(path);
891
+ const responses = buildDefaultResponses(method);
892
+ for (const [code, schema] of Object.entries(responseSchemas)) {
893
+ const existing = responses[code] ?? { description: `HTTP ${code}` };
894
+ responses[code] = {
895
+ ...existing,
896
+ content: { "application/json": { schema } }
897
+ };
898
+ }
890
899
  const route = {
891
900
  method,
892
901
  path,
893
902
  tags,
894
903
  parameters: allParameters,
895
- responses: buildDefaultResponses(method),
904
+ responses,
896
905
  middleware: middlewareArgs.map((m) => m.getText())
897
906
  };
898
907
  if (handlerInfo.summary !== void 0) route.summary = handlerInfo.summary;
@@ -951,6 +960,64 @@ var extractPathParameters = (path) => {
951
960
  }
952
961
  return params;
953
962
  };
963
+ var extractResponseSchemas = (handler) => {
964
+ const result = {};
965
+ const calls = handler.getDescendantsOfKind(SyntaxKind3.CallExpression);
966
+ for (const call of calls) {
967
+ const expr = call.getExpression();
968
+ if (!Node5.isPropertyAccessExpression(expr)) continue;
969
+ const methodName = expr.getName();
970
+ if (methodName !== "json" && methodName !== "send") continue;
971
+ let statusCode = "200";
972
+ const callee = expr.getExpression();
973
+ if (Node5.isCallExpression(callee)) {
974
+ const statusExpr = callee.getExpression();
975
+ if (Node5.isPropertyAccessExpression(statusExpr) && statusExpr.getName() === "status") {
976
+ const statusArg = callee.getArguments()[0];
977
+ if (statusArg && Node5.isNumericLiteral(statusArg)) {
978
+ statusCode = statusArg.getText();
979
+ }
980
+ }
981
+ }
982
+ const args = call.getArguments();
983
+ if (args.length === 0) continue;
984
+ const arg = args[0];
985
+ if (!arg || !Node5.isObjectLiteralExpression(arg)) continue;
986
+ const schema = schemaFromObjectLiteral(arg);
987
+ if (schema && Object.keys(schema.properties ?? {}).length > 0) {
988
+ if (!result[statusCode]) result[statusCode] = schema;
989
+ }
990
+ }
991
+ return result;
992
+ };
993
+ var schemaFromObjectLiteral = (obj) => {
994
+ const properties = {};
995
+ for (const prop of obj.getProperties()) {
996
+ if (!Node5.isPropertyAssignment(prop)) continue;
997
+ const name = prop.getNameNode().getText().replace(/['"]/g, "");
998
+ const init2 = prop.getInitializer();
999
+ if (!init2) continue;
1000
+ properties[name] = schemaFromValue(init2);
1001
+ }
1002
+ return { type: "object", properties };
1003
+ };
1004
+ var schemaFromValue = (expr) => {
1005
+ if (Node5.isStringLiteral(expr) || Node5.isTemplateExpression(expr) || Node5.isNoSubstitutionTemplateLiteral(expr))
1006
+ return { type: "string", example: Node5.isStringLiteral(expr) ? expr.getLiteralValue() : void 0 };
1007
+ if (Node5.isNumericLiteral(expr))
1008
+ return { type: "number", example: Number(expr.getLiteralValue()) };
1009
+ if (expr.getKind() === SyntaxKind3.TrueKeyword || expr.getKind() === SyntaxKind3.FalseKeyword)
1010
+ return { type: "boolean", example: expr.getKind() === SyntaxKind3.TrueKeyword };
1011
+ if (Node5.isNullLiteral(expr))
1012
+ return { type: "null" };
1013
+ if (Node5.isArrayLiteralExpression(expr)) {
1014
+ const items = expr.getElements()[0];
1015
+ return { type: "array", items: items ? schemaFromValue(items) : {} };
1016
+ }
1017
+ if (Node5.isObjectLiteralExpression(expr))
1018
+ return schemaFromObjectLiteral(expr);
1019
+ return {};
1020
+ };
954
1021
  var extractHandlerInfo = (handler) => {
955
1022
  const leadingComments = handler.getLeadingCommentRanges();
956
1023
  if (leadingComments.length === 0) return {};
@@ -3,7 +3,7 @@ import {
3
3
  generate,
4
4
  loadConfig,
5
5
  resolveConfig
6
- } from "./chunk-ZJCRRUX7.js";
6
+ } from "./chunk-KSXE5LV4.js";
7
7
 
8
8
  // src/serve.ts
9
9
  import { createServer } from "http";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flowdoc-gen",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "Auto-generate beautiful API documentation from your Express codebase — no annotations required",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1 +1 @@
1
- *,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.sticky{position:sticky}.top-0{top:0}.mx-auto{margin-left:auto;margin-right:auto}.-mb-px{margin-bottom:-1px}.mb-1{margin-bottom:.25rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.flex{display:flex}.inline-flex{display:inline-flex}.grid{display:grid}.h-12{height:3rem}.h-full{height:100%}.h-screen{height:100vh}.max-h-96{max-height:24rem}.w-10{width:2.5rem}.w-12{width:3rem}.w-24{width:6rem}.w-64{width:16rem}.w-full{width:100%}.min-w-0{min-width:0px}.min-w-\[42px\]{min-width:42px}.min-w-\[52px\]{min-width:52px}.max-w-3xl{max-width:48rem}.max-w-xs{max-width:20rem}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.resize-y{resize:vertical}.grid-cols-\[1fr_auto_1fr\]{grid-template-columns:1fr auto 1fr}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-5{gap:1.25rem}.gap-6{gap:1.5rem}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.self-start{align-self:flex-start}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-b-2{border-bottom-width:2px}.border-l{border-left-width:1px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-\[var\(--brand\)\]{border-color:var(--brand)}.border-red-900\/50{border-color:#7f1d1d80}.border-slate-700{--tw-border-opacity: 1;border-color:rgb(51 65 85 / var(--tw-border-opacity, 1))}.border-slate-800{--tw-border-opacity: 1;border-color:rgb(30 41 59 / var(--tw-border-opacity, 1))}.bg-\[var\(--brand\)\]{background-color:var(--brand)}.bg-amber-500\/15{background-color:#f59e0b26}.bg-blue-500\/15{background-color:#3b82f626}.bg-emerald-500\/15{background-color:#10b98126}.bg-orange-500\/15{background-color:#f9731626}.bg-purple-500\/15{background-color:#a855f726}.bg-red-500\/15{background-color:#ef444426}.bg-red-950\/40{background-color:#450a0a66}.bg-slate-500\/15{background-color:#64748b26}.bg-slate-800{--tw-bg-opacity: 1;background-color:rgb(30 41 59 / var(--tw-bg-opacity, 1))}.bg-slate-900{--tw-bg-opacity: 1;background-color:rgb(15 23 42 / var(--tw-bg-opacity, 1))}.bg-slate-950{--tw-bg-opacity: 1;background-color:rgb(2 6 23 / var(--tw-bg-opacity, 1))}.p-3{padding:.75rem}.p-4{padding:1rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-8{padding-left:2rem;padding-right:2rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-10{padding-top:2.5rem;padding-bottom:2.5rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-5{padding-top:1.25rem;padding-bottom:1.25rem}.pl-0{padding-left:0}.pl-3{padding-left:.75rem}.text-left{text-align:left}.text-center{text-align:center}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.capitalize{text-transform:capitalize}.leading-relaxed{line-height:1.625}.tracking-tight{letter-spacing:-.025em}.tracking-wider{letter-spacing:.05em}.tracking-widest{letter-spacing:.1em}.text-\[var\(--brand\)\]{color:var(--brand)}.text-amber-400{--tw-text-opacity: 1;color:rgb(251 191 36 / var(--tw-text-opacity, 1))}.text-blue-400{--tw-text-opacity: 1;color:rgb(96 165 250 / var(--tw-text-opacity, 1))}.text-emerald-400{--tw-text-opacity: 1;color:rgb(52 211 153 / var(--tw-text-opacity, 1))}.text-green-400{--tw-text-opacity: 1;color:rgb(74 222 128 / var(--tw-text-opacity, 1))}.text-orange-400{--tw-text-opacity: 1;color:rgb(251 146 60 / var(--tw-text-opacity, 1))}.text-purple-400{--tw-text-opacity: 1;color:rgb(192 132 252 / var(--tw-text-opacity, 1))}.text-red-400{--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.text-slate-100{--tw-text-opacity: 1;color:rgb(241 245 249 / var(--tw-text-opacity, 1))}.text-slate-200{--tw-text-opacity: 1;color:rgb(226 232 240 / var(--tw-text-opacity, 1))}.text-slate-300{--tw-text-opacity: 1;color:rgb(203 213 225 / var(--tw-text-opacity, 1))}.text-slate-400{--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity, 1))}.text-slate-500{--tw-text-opacity: 1;color:rgb(100 116 139 / var(--tw-text-opacity, 1))}.text-slate-600{--tw-text-opacity: 1;color:rgb(71 85 105 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.ring-1{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-inset{--tw-ring-inset: inset}.ring-amber-500\/20{--tw-ring-color: rgb(245 158 11 / .2)}.ring-blue-500\/20{--tw-ring-color: rgb(59 130 246 / .2)}.ring-emerald-500\/20{--tw-ring-color: rgb(16 185 129 / .2)}.ring-orange-500\/20{--tw-ring-color: rgb(249 115 22 / .2)}.ring-purple-500\/20{--tw-ring-color: rgb(168 85 247 / .2)}.ring-red-500\/20{--tw-ring-color: rgb(239 68 68 / .2)}.ring-slate-500\/20{--tw-ring-color: rgb(100 116 139 / .2)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}:root{--brand: #6366f1}*{box-sizing:border-box}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,Inter,Segoe UI,sans-serif;-webkit-font-smoothing:antialiased}::-webkit-scrollbar{width:4px;height:4px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:#334155;border-radius:2px}.placeholder\:text-slate-600::-moz-placeholder{--tw-text-opacity: 1;color:rgb(71 85 105 / var(--tw-text-opacity, 1))}.placeholder\:text-slate-600::placeholder{--tw-text-opacity: 1;color:rgb(71 85 105 / var(--tw-text-opacity, 1))}.hover\:bg-slate-800\/50:hover{background-color:#1e293b80}.hover\:text-slate-200:hover{--tw-text-opacity: 1;color:rgb(226 232 240 / var(--tw-text-opacity, 1))}.hover\:text-slate-300:hover{--tw-text-opacity: 1;color:rgb(203 213 225 / var(--tw-text-opacity, 1))}.hover\:opacity-90:hover{opacity:.9}.focus\:border-\[var\(--brand\)\]:focus{border-color:var(--brand)}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.disabled\:opacity-50:disabled{opacity:.5}
1
+ *,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.sticky{position:sticky}.top-0{top:0}.mx-auto{margin-left:auto;margin-right:auto}.-mb-px{margin-bottom:-1px}.mb-1{margin-bottom:.25rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.flex{display:flex}.inline-flex{display:inline-flex}.grid{display:grid}.h-12{height:3rem}.h-full{height:100%}.h-screen{height:100vh}.max-h-96{max-height:24rem}.w-10{width:2.5rem}.w-12{width:3rem}.w-24{width:6rem}.w-64{width:16rem}.w-full{width:100%}.min-w-0{min-width:0px}.min-w-\[42px\]{min-width:42px}.min-w-\[52px\]{min-width:52px}.max-w-3xl{max-width:48rem}.max-w-xs{max-width:20rem}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.resize-y{resize:vertical}.grid-cols-\[1fr_auto_1fr\]{grid-template-columns:1fr auto 1fr}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-5{gap:1.25rem}.gap-6{gap:1.5rem}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.self-start{align-self:flex-start}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-b-2{border-bottom-width:2px}.border-l{border-left-width:1px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-\[var\(--brand\)\]{border-color:var(--brand)}.border-red-900\/50{border-color:#7f1d1d80}.border-slate-700{--tw-border-opacity: 1;border-color:rgb(51 65 85 / var(--tw-border-opacity, 1))}.border-slate-800{--tw-border-opacity: 1;border-color:rgb(30 41 59 / var(--tw-border-opacity, 1))}.bg-\[var\(--brand\)\]{background-color:var(--brand)}.bg-amber-500\/15{background-color:#f59e0b26}.bg-blue-500\/15{background-color:#3b82f626}.bg-emerald-500\/15{background-color:#10b98126}.bg-orange-500\/15{background-color:#f9731626}.bg-purple-500\/15{background-color:#a855f726}.bg-red-500\/15{background-color:#ef444426}.bg-red-950\/40{background-color:#450a0a66}.bg-slate-500\/15{background-color:#64748b26}.bg-slate-800{--tw-bg-opacity: 1;background-color:rgb(30 41 59 / var(--tw-bg-opacity, 1))}.bg-slate-900{--tw-bg-opacity: 1;background-color:rgb(15 23 42 / var(--tw-bg-opacity, 1))}.bg-slate-950{--tw-bg-opacity: 1;background-color:rgb(2 6 23 / var(--tw-bg-opacity, 1))}.p-3{padding:.75rem}.p-4{padding:1rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-8{padding-left:2rem;padding-right:2rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-10{padding-top:2.5rem;padding-bottom:2.5rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-5{padding-top:1.25rem;padding-bottom:1.25rem}.pl-0{padding-left:0}.pl-1{padding-left:.25rem}.pl-3{padding-left:.75rem}.pt-2{padding-top:.5rem}.text-left{text-align:left}.text-center{text-align:center}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.capitalize{text-transform:capitalize}.leading-relaxed{line-height:1.625}.tracking-tight{letter-spacing:-.025em}.tracking-wider{letter-spacing:.05em}.tracking-widest{letter-spacing:.1em}.text-\[var\(--brand\)\]{color:var(--brand)}.text-amber-400{--tw-text-opacity: 1;color:rgb(251 191 36 / var(--tw-text-opacity, 1))}.text-blue-400{--tw-text-opacity: 1;color:rgb(96 165 250 / var(--tw-text-opacity, 1))}.text-emerald-400{--tw-text-opacity: 1;color:rgb(52 211 153 / var(--tw-text-opacity, 1))}.text-green-400{--tw-text-opacity: 1;color:rgb(74 222 128 / var(--tw-text-opacity, 1))}.text-orange-400{--tw-text-opacity: 1;color:rgb(251 146 60 / var(--tw-text-opacity, 1))}.text-purple-400{--tw-text-opacity: 1;color:rgb(192 132 252 / var(--tw-text-opacity, 1))}.text-red-400{--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.text-slate-100{--tw-text-opacity: 1;color:rgb(241 245 249 / var(--tw-text-opacity, 1))}.text-slate-200{--tw-text-opacity: 1;color:rgb(226 232 240 / var(--tw-text-opacity, 1))}.text-slate-300{--tw-text-opacity: 1;color:rgb(203 213 225 / var(--tw-text-opacity, 1))}.text-slate-400{--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity, 1))}.text-slate-500{--tw-text-opacity: 1;color:rgb(100 116 139 / var(--tw-text-opacity, 1))}.text-slate-600{--tw-text-opacity: 1;color:rgb(71 85 105 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.ring-1{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-inset{--tw-ring-inset: inset}.ring-amber-500\/20{--tw-ring-color: rgb(245 158 11 / .2)}.ring-blue-500\/20{--tw-ring-color: rgb(59 130 246 / .2)}.ring-emerald-500\/20{--tw-ring-color: rgb(16 185 129 / .2)}.ring-orange-500\/20{--tw-ring-color: rgb(249 115 22 / .2)}.ring-purple-500\/20{--tw-ring-color: rgb(168 85 247 / .2)}.ring-red-500\/20{--tw-ring-color: rgb(239 68 68 / .2)}.ring-slate-500\/20{--tw-ring-color: rgb(100 116 139 / .2)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}:root{--brand: #6366f1}*{box-sizing:border-box}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,Inter,Segoe UI,sans-serif;-webkit-font-smoothing:antialiased}::-webkit-scrollbar{width:4px;height:4px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:#334155;border-radius:2px}.placeholder\:text-slate-600::-moz-placeholder{--tw-text-opacity: 1;color:rgb(71 85 105 / var(--tw-text-opacity, 1))}.placeholder\:text-slate-600::placeholder{--tw-text-opacity: 1;color:rgb(71 85 105 / var(--tw-text-opacity, 1))}.hover\:bg-slate-800\/50:hover{background-color:#1e293b80}.hover\:text-slate-200:hover{--tw-text-opacity: 1;color:rgb(226 232 240 / var(--tw-text-opacity, 1))}.hover\:text-slate-300:hover{--tw-text-opacity: 1;color:rgb(203 213 225 / var(--tw-text-opacity, 1))}.hover\:opacity-90:hover{opacity:.9}.focus\:border-\[var\(--brand\)\]:focus{border-color:var(--brand)}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.disabled\:opacity-50:disabled{opacity:.5}