@ragrails/api-playground-react 0.1.0

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.
Files changed (39) hide show
  1. package/README.md +32 -0
  2. package/dist/index.cjs +15 -0
  3. package/dist/index.js +2827 -0
  4. package/dist/src/components/ui/Badge.d.ts +21 -0
  5. package/dist/src/components/ui/Button.d.ts +14 -0
  6. package/dist/src/components/ui/Card.d.ts +12 -0
  7. package/dist/src/components/ui/Checkbox.d.ts +14 -0
  8. package/dist/src/components/ui/CodeBlock.d.ts +18 -0
  9. package/dist/src/components/ui/ColorField.d.ts +11 -0
  10. package/dist/src/components/ui/CopyButton.d.ts +13 -0
  11. package/dist/src/components/ui/Icon.d.ts +14 -0
  12. package/dist/src/components/ui/IconButton.d.ts +11 -0
  13. package/dist/src/components/ui/MethodSelect.d.ts +13 -0
  14. package/dist/src/components/ui/ResponseEmptyState.d.ts +11 -0
  15. package/dist/src/components/ui/ResponseLoadingState.d.ts +9 -0
  16. package/dist/src/components/ui/Select.d.ts +17 -0
  17. package/dist/src/components/ui/Skeleton.d.ts +13 -0
  18. package/dist/src/components/ui/Spinner.d.ts +10 -0
  19. package/dist/src/components/ui/Switch.d.ts +11 -0
  20. package/dist/src/components/ui/Tabs.d.ts +18 -0
  21. package/dist/src/components/ui/TextField.d.ts +16 -0
  22. package/dist/src/components/ui/index.d.ts +26 -0
  23. package/dist/src/features/api-widget/ApiConsole.d.ts +13 -0
  24. package/dist/src/features/api-widget/ApiWidget.d.ts +24 -0
  25. package/dist/src/features/api-widget/ImportCard.d.ts +11 -0
  26. package/dist/src/features/api-widget/RequestSnippet.d.ts +13 -0
  27. package/dist/src/features/api-widget/curl.d.ts +7 -0
  28. package/dist/src/features/api-widget/executor.d.ts +4 -0
  29. package/dist/src/features/api-widget/index.d.ts +10 -0
  30. package/dist/src/features/api-widget/request-model.d.ts +21 -0
  31. package/dist/src/features/api-widget/snippets.d.ts +9 -0
  32. package/dist/src/features/api-widget/types.d.ts +41 -0
  33. package/dist/src/index.d.ts +1 -0
  34. package/dist/src/lib/clipboard.d.ts +15 -0
  35. package/dist/src/lib/cn.d.ts +2 -0
  36. package/dist/src/lib/highlight.d.ts +8 -0
  37. package/dist/src/types/index.d.ts +32 -0
  38. package/dist/styles.css +2 -0
  39. package/package.json +57 -0
@@ -0,0 +1,21 @@
1
+ import { default as React } from 'react';
2
+ import { HttpMethod } from '../../../types';
3
+ export type BadgeTone = 'neutral' | 'primary' | 'success' | 'error' | 'warning' | 'info';
4
+ interface BadgeProps {
5
+ tone?: BadgeTone;
6
+ className?: string;
7
+ children: React.ReactNode;
8
+ }
9
+ export declare const Badge: React.FC<BadgeProps>;
10
+ /** Badge color-coded by HTTP method, matching the request builder. */
11
+ export declare const MethodBadge: React.FC<{
12
+ method: HttpMethod;
13
+ className?: string;
14
+ }>;
15
+ /** Badge for an HTTP status: green for 2xx, amber for 3xx, red otherwise. */
16
+ export declare const StatusBadge: React.FC<{
17
+ status: number;
18
+ statusText?: string;
19
+ className?: string;
20
+ }>;
21
+ export {};
@@ -0,0 +1,14 @@
1
+ import { default as React } from 'react';
2
+ export type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'danger';
3
+ export type ButtonSize = 'sm' | 'md' | 'lg';
4
+ interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
5
+ variant?: ButtonVariant;
6
+ size?: ButtonSize;
7
+ isLoading?: boolean;
8
+ /** Icon rendered before the label. */
9
+ leftIcon?: React.ReactNode;
10
+ /** Icon rendered after the label. */
11
+ rightIcon?: React.ReactNode;
12
+ }
13
+ export declare const Button: React.FC<ButtonProps>;
14
+ export {};
@@ -0,0 +1,12 @@
1
+ import { default as React } from 'react';
2
+ interface CardProps {
3
+ /** Muted label rendered above the card (e.g. "Get Users", "Sample Response"). */
4
+ label?: string;
5
+ /** Remove inner padding — useful when the card hosts its own toolbar/body. */
6
+ flush?: boolean;
7
+ className?: string;
8
+ children: React.ReactNode;
9
+ }
10
+ /** Elevated, rounded surface container with an optional caption above it. */
11
+ export declare const Card: React.FC<CardProps>;
12
+ export {};
@@ -0,0 +1,14 @@
1
+ import { default as React } from 'react';
2
+ export type CheckboxSize = 'sm' | 'md';
3
+ interface CheckboxProps {
4
+ checked: boolean;
5
+ onChange: (checked: boolean) => void;
6
+ label?: string;
7
+ disabled?: boolean;
8
+ size?: CheckboxSize;
9
+ className?: string;
10
+ 'aria-label'?: string;
11
+ }
12
+ /** Controlled checkbox with the same theme tokens as form fields. */
13
+ export declare const Checkbox: React.FC<CheckboxProps>;
14
+ export {};
@@ -0,0 +1,18 @@
1
+ import { default as React } from 'react';
2
+ import { CodeLanguage } from '../../../lib/highlight';
3
+ interface CodeBlockProps {
4
+ code: string;
5
+ language?: CodeLanguage;
6
+ showLineNumbers?: boolean;
7
+ copyable?: boolean;
8
+ /** Max height before the body scrolls (CSS length). */
9
+ maxHeight?: string;
10
+ /** Reveal each line with a staggered fade-in from the top (e.g. when a response arrives). */
11
+ reveal?: boolean;
12
+ /** Per-line stagger for `reveal`, in ms. */
13
+ revealStagger?: number;
14
+ className?: string;
15
+ }
16
+ /** Read-only, syntax-highlighted code surface with optional line numbers + copy. */
17
+ export declare const CodeBlock: React.FC<CodeBlockProps>;
18
+ export {};
@@ -0,0 +1,11 @@
1
+ import { default as React } from 'react';
2
+ interface ColorFieldProps {
3
+ label?: string;
4
+ /** Hex color value, e.g. "#6760e3". */
5
+ value: string;
6
+ onChange: (value: string) => void;
7
+ className?: string;
8
+ }
9
+ /** Swatch + hex input pair for picking a theme color. */
10
+ export declare const ColorField: React.FC<ColorFieldProps>;
11
+ export {};
@@ -0,0 +1,13 @@
1
+ import { default as React } from 'react';
2
+ import { IconButtonVariant, IconButtonSize } from './IconButton';
3
+ interface CopyButtonProps {
4
+ /** Text to copy to the clipboard. */
5
+ value: string;
6
+ variant?: IconButtonVariant;
7
+ size?: IconButtonSize;
8
+ className?: string;
9
+ label?: string;
10
+ }
11
+ /** Icon button that copies `value` and briefly flips to a check mark. */
12
+ export declare const CopyButton: React.FC<CopyButtonProps>;
13
+ export {};
@@ -0,0 +1,14 @@
1
+ import { default as React } from 'react';
2
+ export type IconName = 'copy' | 'check' | 'download' | 'send' | 'share' | 'code' | 'arrow-left' | 'arrow-right' | 'chevron-down' | 'trash' | 'plus' | 'moon' | 'sun' | 'palette' | 'magic' | 'restart' | 'close' | 'eye' | 'eye-closed';
3
+ interface IconProps extends Omit<React.SVGProps<SVGSVGElement>, 'name'> {
4
+ name: IconName;
5
+ /** Size in px (sets width & height). Defaults to 1em so width/height utilities work too. */
6
+ size?: number | string;
7
+ }
8
+ /**
9
+ * Themed icon. Inherits color from `currentColor` (use text utilities) and sizes
10
+ * to the surrounding font size by default. Decorative by default (`aria-hidden`);
11
+ * pass an `aria-label` to make it meaningful to screen readers.
12
+ */
13
+ export declare const Icon: React.FC<IconProps>;
14
+ export {};
@@ -0,0 +1,11 @@
1
+ import { default as React } from 'react';
2
+ export type IconButtonVariant = 'ghost' | 'solid' | 'surface';
3
+ export type IconButtonSize = 'sm' | 'md';
4
+ interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
5
+ variant?: IconButtonVariant;
6
+ size?: IconButtonSize;
7
+ /** Accessible label — required since the button has no text. */
8
+ 'aria-label': string;
9
+ }
10
+ export declare const IconButton: React.FC<IconButtonProps>;
11
+ export {};
@@ -0,0 +1,13 @@
1
+ import { default as React } from 'react';
2
+ import { HttpMethod } from '../../../types';
3
+ interface MethodSelectProps {
4
+ value: HttpMethod;
5
+ onChange: (method: HttpMethod) => void;
6
+ /** Methods to offer. Defaults to the full set. */
7
+ methods?: HttpMethod[];
8
+ disabled?: boolean;
9
+ className?: string;
10
+ }
11
+ /** Color-coded HTTP method dropdown for the request bar. */
12
+ export declare const MethodSelect: React.FC<MethodSelectProps>;
13
+ export {};
@@ -0,0 +1,11 @@
1
+ import { default as React } from 'react';
2
+ interface ResponseEmptyStateProps {
3
+ title?: string;
4
+ description?: string;
5
+ /** Illustration size in px. */
6
+ size?: number;
7
+ className?: string;
8
+ }
9
+ /** Empty state for the response panel, shown until a request returns. */
10
+ export declare const ResponseEmptyState: React.FC<ResponseEmptyStateProps>;
11
+ export {};
@@ -0,0 +1,9 @@
1
+ import { default as React } from 'react';
2
+ interface ResponseLoadingStateProps {
3
+ className?: string;
4
+ /** Minimum height of the shimmering area (CSS length). */
5
+ minHeight?: string | number;
6
+ }
7
+ /** Full-bleed shimmering surface shown in the response panel while a request is in flight. */
8
+ export declare const ResponseLoadingState: React.FC<ResponseLoadingStateProps>;
9
+ export {};
@@ -0,0 +1,17 @@
1
+ export interface SelectItem<T extends string> {
2
+ id: T;
3
+ label: string;
4
+ className?: string;
5
+ }
6
+ interface SelectProps<T extends string> {
7
+ items: SelectItem<T>[];
8
+ value: T;
9
+ onChange: (value: T) => void;
10
+ size?: 'sm' | 'md';
11
+ disabled?: boolean;
12
+ minWidthClassName?: string;
13
+ className?: string;
14
+ }
15
+ /** Compact themed dropdown using the same behavior as the HTTP method selector. */
16
+ export declare function Select<T extends string>({ items, value, onChange, size, disabled, minWidthClassName, className, }: SelectProps<T>): import("react").JSX.Element;
17
+ export {};
@@ -0,0 +1,13 @@
1
+ import { default as React } from 'react';
2
+ interface SkeletonProps {
3
+ className?: string;
4
+ /** Inline width (CSS length). */
5
+ width?: string | number;
6
+ /** Inline height (CSS length). */
7
+ height?: string | number;
8
+ /** Corner radius. */
9
+ rounded?: 'sm' | 'md' | 'lg' | 'full';
10
+ }
11
+ /** Placeholder block with a light shimmer sweep, for loading states. */
12
+ export declare const Skeleton: React.FC<SkeletonProps>;
13
+ export {};
@@ -0,0 +1,10 @@
1
+ import { default as React } from 'react';
2
+ interface SpinnerProps {
3
+ /** Diameter in pixels. */
4
+ size?: number;
5
+ className?: string;
6
+ label?: string;
7
+ }
8
+ /** Indeterminate loading spinner tinted with the primary color. */
9
+ export declare const Spinner: React.FC<SpinnerProps>;
10
+ export {};
@@ -0,0 +1,11 @@
1
+ import { default as React } from 'react';
2
+ interface SwitchProps {
3
+ checked: boolean;
4
+ onChange: (checked: boolean) => void;
5
+ label?: string;
6
+ disabled?: boolean;
7
+ className?: string;
8
+ }
9
+ /** Accessible on/off toggle. The track fills with the primary color when on. */
10
+ export declare const Switch: React.FC<SwitchProps>;
11
+ export {};
@@ -0,0 +1,18 @@
1
+ import { default as React } from 'react';
2
+ export interface TabItem {
3
+ id: string;
4
+ label: string;
5
+ badge?: string | number;
6
+ }
7
+ interface TabsProps {
8
+ items: TabItem[];
9
+ activeId: string;
10
+ onChange: (id: string) => void;
11
+ /** Visual style: `underline` (default) or `segmented` pill group. */
12
+ variant?: 'underline' | 'segmented';
13
+ size?: 'sm' | 'md';
14
+ className?: string;
15
+ }
16
+ /** Themed tab bar with a sliding active indicator. */
17
+ export declare const Tabs: React.FC<TabsProps>;
18
+ export {};
@@ -0,0 +1,16 @@
1
+ import { default as React } from 'react';
2
+ export type TextFieldSize = 'sm' | 'md' | 'lg';
3
+ interface TextFieldProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {
4
+ label?: string;
5
+ error?: string;
6
+ hint?: string;
7
+ size?: TextFieldSize;
8
+ /** Content rendered inside the field on the left (e.g. an icon or method badge). */
9
+ leftSlot?: React.ReactNode;
10
+ /** Content rendered inside the field on the right. */
11
+ rightSlot?: React.ReactNode;
12
+ containerClassName?: string;
13
+ }
14
+ /** Themed text input with optional label, inline slots, and error/hint text. */
15
+ export declare const TextField: React.FC<TextFieldProps>;
16
+ export {};
@@ -0,0 +1,26 @@
1
+ export { Icon } from './Icon';
2
+ export type { IconName } from './Icon';
3
+ export { Button } from './Button';
4
+ export type { ButtonVariant, ButtonSize } from './Button';
5
+ export { IconButton } from './IconButton';
6
+ export type { IconButtonVariant, IconButtonSize } from './IconButton';
7
+ export { CopyButton } from './CopyButton';
8
+ export { Badge, MethodBadge, StatusBadge } from './Badge';
9
+ export type { BadgeTone } from './Badge';
10
+ export { Spinner } from './Spinner';
11
+ export { Switch } from './Switch';
12
+ export { Checkbox } from './Checkbox';
13
+ export type { CheckboxSize } from './Checkbox';
14
+ export { Card } from './Card';
15
+ export { Tabs } from './Tabs';
16
+ export type { TabItem } from './Tabs';
17
+ export { TextField } from './TextField';
18
+ export type { TextFieldSize } from './TextField';
19
+ export { Select } from './Select';
20
+ export type { SelectItem } from './Select';
21
+ export { MethodSelect } from './MethodSelect';
22
+ export { ColorField } from './ColorField';
23
+ export { CodeBlock } from './CodeBlock';
24
+ export { ResponseEmptyState } from './ResponseEmptyState';
25
+ export { ResponseLoadingState } from './ResponseLoadingState';
26
+ export { Skeleton } from './Skeleton';
@@ -0,0 +1,13 @@
1
+ import { default as React } from 'react';
2
+ import { WidgetRequest, WidgetSendHandler } from './types';
3
+ export interface ApiConsoleProps {
4
+ request: WidgetRequest;
5
+ onRequestChange?: (request: WidgetRequest) => void;
6
+ onSend?: WidgetSendHandler;
7
+ editable?: boolean;
8
+ onBack?: () => void;
9
+ onImport?: () => void;
10
+ className?: string;
11
+ }
12
+ /** Interactive request builder + response console used by the documentation widget. */
13
+ export declare const ApiConsole: React.FC<ApiConsoleProps>;
@@ -0,0 +1,24 @@
1
+ import { default as React } from 'react';
2
+ export type ApiWidgetMode = 'dark' | 'light' | 'system';
3
+ export interface ApiWidgetCustomization {
4
+ primary?: string;
5
+ background?: string;
6
+ }
7
+ export interface ApiWidgetProps {
8
+ request: string;
9
+ title?: string;
10
+ sampleResponse?: string;
11
+ onUpdateRequest?: (request: string) => void;
12
+ editable?: boolean;
13
+ allowImport?: boolean;
14
+ /** Color theme: `'dark'` (default), `'light'`, or `'system'` (follows the OS). */
15
+ mode?: ApiWidgetMode;
16
+ /**
17
+ * When true, the start snippet tracks live edits made in the console.
18
+ * Default false — the snippet stays pinned to the documented `request`.
19
+ */
20
+ syncSnippet?: boolean;
21
+ customization?: ApiWidgetCustomization;
22
+ }
23
+ /** Full embeddable API widget with cURL as its public request source of truth. */
24
+ export declare const ApiWidget: React.FC<ApiWidgetProps>;
@@ -0,0 +1,11 @@
1
+ import { default as React } from 'react';
2
+ import { WidgetRequest } from './types';
3
+ interface ImportCardProps {
4
+ /** Called with the parsed request when a valid cURL command is imported. */
5
+ onImport: (request: WidgetRequest, curl: string) => void;
6
+ onCancel?: () => void;
7
+ className?: string;
8
+ }
9
+ /** Inline card for importing a request by pasting a cURL command. */
10
+ export declare const ImportCard: React.FC<ImportCardProps>;
11
+ export {};
@@ -0,0 +1,13 @@
1
+ import { default as React } from 'react';
2
+ import { WidgetRequest } from './types';
3
+ interface RequestSnippetProps {
4
+ request: WidgetRequest;
5
+ /** Called when the user clicks "Try it out". */
6
+ onTryItOut?: () => void;
7
+ }
8
+ /**
9
+ * Documentation view of a request: language-tabbed code snippet with a
10
+ * "Try it out" action, plus an optional sample response.
11
+ */
12
+ export declare const RequestSnippet: React.FC<RequestSnippetProps>;
13
+ export {};
@@ -0,0 +1,7 @@
1
+ import { WidgetRequest } from './types';
2
+ /**
3
+ * Parse a cURL command into a WidgetRequest. Returns null if no URL is found.
4
+ * Supports common shell quoting, escaped quotes, --url, repeated data flags,
5
+ * header flags, and Authorization auth extraction.
6
+ */
7
+ export declare function parseCurl(input: string): WidgetRequest | null;
@@ -0,0 +1,4 @@
1
+ import { WidgetRequest, WidgetResponse } from './types';
2
+ export declare function widgetErrorResponse(error: unknown, startedAt?: number): WidgetResponse;
3
+ export declare function executeWidgetRequest(request: WidgetRequest): Promise<WidgetResponse>;
4
+ export declare function mockWidgetResponse(request: WidgetRequest): WidgetResponse;
@@ -0,0 +1,10 @@
1
+ export { ApiWidget } from './ApiWidget';
2
+ export type { ApiWidgetCustomization, ApiWidgetMode, ApiWidgetProps } from './ApiWidget';
3
+ export { RequestSnippet } from './RequestSnippet';
4
+ export { ApiConsole } from './ApiConsole';
5
+ export type { ApiConsoleProps } from './ApiConsole';
6
+ export { ImportCard } from './ImportCard';
7
+ export { executeWidgetRequest, mockWidgetResponse, widgetErrorResponse } from './executor';
8
+ export { parseCurl } from './curl';
9
+ export { generateSnippet, highlightFor, SNIPPET_LANGUAGES } from './snippets';
10
+ export type { WidgetRequest, WidgetHeader, WidgetAuth, WidgetResponse, WidgetSendHandler, SnippetLanguage, } from './types';
@@ -0,0 +1,21 @@
1
+ import { HttpMethod } from '../../../types';
2
+ import { WidgetAuth, WidgetHeader, WidgetRequest } from './types';
3
+ export interface EditableHeader extends WidgetHeader {
4
+ enabled: boolean;
5
+ }
6
+ export interface RequestParts {
7
+ method: HttpMethod;
8
+ url: string;
9
+ body: string;
10
+ auth: WidgetAuth;
11
+ headers: EditableHeader[];
12
+ }
13
+ export declare function authHeader(auth: WidgetAuth): EditableHeader | null;
14
+ export declare function isSameHeaderKey(a: string, b: string): boolean;
15
+ export declare function authFromHeader(header?: WidgetHeader | EditableHeader): WidgetAuth;
16
+ export declare function isAuthHeader(header: WidgetHeader | EditableHeader, auth: WidgetAuth): boolean;
17
+ export declare function initialAuth(request: WidgetRequest): WidgetAuth;
18
+ export declare function initialHeaders(request: WidgetRequest, auth: WidgetAuth): EditableHeader[];
19
+ export declare function syncAuthHeader(headers: EditableHeader[], nextAuth: WidgetAuth, previousAuth: WidgetAuth): EditableHeader[];
20
+ export declare function requestKey(request: WidgetRequest): string;
21
+ export declare function requestFromParts(base: WidgetRequest, parts: RequestParts): WidgetRequest;
@@ -0,0 +1,9 @@
1
+ import { WidgetRequest, SnippetLanguage } from './types';
2
+ import { CodeLanguage } from '../../../lib/highlight';
3
+ export declare const SNIPPET_LANGUAGES: {
4
+ id: SnippetLanguage;
5
+ label: string;
6
+ }[];
7
+ /** Map a snippet language to the highlighter grammar. */
8
+ export declare function highlightFor(lang: SnippetLanguage): CodeLanguage;
9
+ export declare function generateSnippet(req: WidgetRequest, lang: SnippetLanguage): string;
@@ -0,0 +1,41 @@
1
+ import { HttpMethod } from '../../../types';
2
+ export interface WidgetHeader {
3
+ key: string;
4
+ value: string;
5
+ }
6
+ export type WidgetAuth = {
7
+ type: 'none';
8
+ } | {
9
+ type: 'bearer';
10
+ token: string;
11
+ } | {
12
+ type: 'apiKey';
13
+ key: string;
14
+ value: string;
15
+ in: 'header';
16
+ };
17
+ /** A single documented API request that powers a widget. */
18
+ export interface WidgetRequest {
19
+ /** Caption shown above the snippet card (e.g. "Get Users"). */
20
+ title: string;
21
+ method: HttpMethod;
22
+ url: string;
23
+ headers?: WidgetHeader[];
24
+ /** Authentication config used by snippets and the interactive console. */
25
+ auth?: WidgetAuth;
26
+ /** Request body as a string (typically JSON). */
27
+ body?: string;
28
+ /** Example response body (JSON string) shown under the snippet. */
29
+ sampleResponse?: string;
30
+ }
31
+ export interface WidgetResponse {
32
+ status: number;
33
+ statusText: string;
34
+ headers: WidgetHeader[];
35
+ body: string;
36
+ timeMs: number;
37
+ size: string;
38
+ error?: string;
39
+ }
40
+ export type WidgetSendHandler = (request: WidgetRequest) => Promise<WidgetResponse> | WidgetResponse;
41
+ export type SnippetLanguage = 'curl' | 'javascript' | 'python' | 'go';
@@ -0,0 +1 @@
1
+ export * from '../features/api-widget';
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Copy text to clipboard with fallback support for iframes and restricted contexts
3
+ * @param text - The text to copy to clipboard
4
+ * @returns Promise that resolves to true if successful, false otherwise
5
+ */
6
+ export declare function copyToClipboard(text: string): Promise<boolean>;
7
+ /**
8
+ * Custom hook for copy to clipboard functionality with visual feedback
9
+ * @param resetDelay - Time in milliseconds before resetting copied state (default: 2000)
10
+ * @returns Object with copy function and copied state
11
+ */
12
+ export declare function useCopyToClipboard(resetDelay?: number): {
13
+ copy: (text: string) => Promise<boolean>;
14
+ copied: boolean;
15
+ };
@@ -0,0 +1,2 @@
1
+ /** Join class names, dropping falsy values. */
2
+ export declare function cn(...classes: Array<string | false | null | undefined>): string;
@@ -0,0 +1,8 @@
1
+ import { default as React } from 'react';
2
+ export type CodeLanguage = 'json' | 'bash' | 'javascript' | 'python' | 'go' | 'plain';
3
+ /**
4
+ * Tokenize a single line with Prism and render it as themed React nodes.
5
+ * Per-line on purpose: CodeBlock owns line numbers and the staggered reveal, so
6
+ * Prism only colors the text — numbering and animation are untouched.
7
+ */
8
+ export declare function highlightLine(line: string, language: CodeLanguage): React.ReactNode;
@@ -0,0 +1,32 @@
1
+ export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
2
+ export interface Header {
3
+ id: string;
4
+ key: string;
5
+ value: string;
6
+ enabled: boolean;
7
+ }
8
+ export type AuthenticationType = 'None' | 'Bearer';
9
+ export interface Authentication {
10
+ type: AuthenticationType;
11
+ token: string;
12
+ enabled: boolean;
13
+ }
14
+ export interface ApiRequest {
15
+ url: string;
16
+ method: HttpMethod;
17
+ headers: Header[];
18
+ body: string;
19
+ authentication?: Authentication;
20
+ }
21
+ export interface ApiResponse {
22
+ status: number;
23
+ statusText: string;
24
+ headers: Record<string, string>;
25
+ data: any;
26
+ time: number;
27
+ size: number;
28
+ }
29
+ export type TabType = 'body' | 'headers' | 'authorization';
30
+ export type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'danger';
31
+ export type ButtonSize = 'sm' | 'md' | 'lg';
32
+ export type InputType = 'text' | 'url' | 'password';
@@ -0,0 +1,2 @@
1
+ /*! tailwindcss v4.3.1 | MIT License | https://tailwindcss.com */
2
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-duration:initial;--tw-ease:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}@layer theme{:root,:host{--font-sans:system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-500:oklch(76.9% .188 70.08);--color-green-500:oklch(72.3% .219 149.579);--color-sky-400:oklch(74.6% .16 232.661);--color-sky-500:oklch(68.5% .169 237.323);--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--font-weight-medium:500;--font-weight-semibold:600;--leading-relaxed:1.625;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--ease-out:cubic-bezier(0, 0, .2, 1);--animate-spin:spin 1s linear infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--font-heading:system-ui, -apple-system, "Segoe UI", Roboto, sans-serif}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}[data-theme] button:not(:disabled),[data-theme] [role=button]:not([aria-disabled=true]){cursor:pointer}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.absolute{position:absolute}.relative{position:relative}.inset-0{inset:0}.top-2{top:calc(var(--spacing) * 2)}.top-5{top:calc(var(--spacing) * 5)}.top-full{top:100%}.right-2{right:calc(var(--spacing) * 2)}.right-5{right:calc(var(--spacing) * 5)}.-bottom-px{bottom:-1px}.left-0{left:0}.isolate{isolation:isolate}.-z-10{z-index:calc(10 * -1)}.z-0{z-index:0}.z-10{z-index:10}.z-20{z-index:20}.col-start-2{grid-column-start:2}.row-span-2{grid-row:span 2/span 2}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.mt-1{margin-top:var(--spacing)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mr-4{margin-right:calc(var(--spacing) * 4)}.mb-1{margin-bottom:var(--spacing)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.ml-1\.5{margin-left:calc(var(--spacing) * 1.5)}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.\[field-sizing\:content\]{field-sizing:content}.h-0\.5{height:calc(var(--spacing) * .5)}.h-3{height:calc(var(--spacing) * 3)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-full{height:100%}.min-h-0{min-height:0}.min-h-10{min-height:calc(var(--spacing) * 10)}.w-3{width:calc(var(--spacing) * 3)}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-7{width:calc(var(--spacing) * 7)}.w-8{width:calc(var(--spacing) * 8)}.w-9{width:calc(var(--spacing) * 9)}.w-11{width:calc(var(--spacing) * 11)}.w-full{width:100%}.w-max{width:max-content}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:0}.min-w-28{min-width:calc(var(--spacing) * 28)}.min-w-\[7rem\]{min-width:7rem}.min-w-full{min-width:100%}.flex-1{flex:1}.shrink-0{flex-shrink:0}.-translate-x-full{--tw-translate-x:-100%;translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-1{--tw-translate-x:var(--spacing);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-6{--tw-translate-x:calc(var(--spacing) * 6);translate:var(--tw-translate-x) var(--tw-translate-y)}.rotate-180{rotate:180deg}.-skew-x-12{--tw-skew-x:skewX(calc(12deg * -1));transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-\[shimmer_2s_linear_infinite\]{animation:2s linear infinite shimmer}.animate-spin{animation:var(--animate-spin)}.cursor-pointer{cursor:pointer}.resize{resize:both}.resize-none{resize:none}.grid-cols-\[auto_1fr_auto\]{grid-template-columns:auto 1fr auto}.\[grid-template-rows\:1fr\]{grid-template-rows:1fr}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(var(--spacing) * var(--tw-space-y-reverse));margin-block-end:calc(var(--spacing) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2.5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-y{border-block-style:var(--tw-border-style);border-block-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-b-0{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-\[\#52b788\]\/25{border-color:oklab(70.6413% -.111726 .0387149/.25)}.border-\[\#FC7070\]\/20{border-color:oklab(71.4755% .158854 .0655041/.2)}.border-amber-500\/30{border-color:#f99c004d}@supports (color:color-mix(in lab, red, red)){.border-amber-500\/30{border-color:color-mix(in oklab, var(--color-amber-500) 30%, transparent)}}.border-border{border-color:var(--border)}.border-current{border-color:currentColor}.border-primary,.border-primary\/30{border-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.border-primary\/30{border-color:color-mix(in oklab, var(--primary) 30%, transparent)}}.border-red-500{border-color:var(--color-red-500)}.border-red-500\/60{border-color:#fb2c3699}@supports (color:color-mix(in lab, red, red)){.border-red-500\/60{border-color:color-mix(in oklab, var(--color-red-500) 60%, transparent)}}.border-sky-500\/30{border-color:#00a5ef4d}@supports (color:color-mix(in lab, red, red)){.border-sky-500\/30{border-color:color-mix(in oklab, var(--color-sky-500) 30%, transparent)}}.border-transparent{border-color:#0000}.border-t-primary{border-top-color:var(--primary)}.border-t-transparent{border-top-color:#0000}.bg-\[\#4A0F0F\]{background-color:#4a0f0f}.bg-\[\#52b788\]\/15{background-color:oklab(70.6413% -.111726 .0387149/.15)}.bg-\[\#EF5350\]{background-color:#ef5350}.bg-amber-500\/15{background-color:#f99c0026}@supports (color:color-mix(in lab, red, red)){.bg-amber-500\/15{background-color:color-mix(in oklab, var(--color-amber-500) 15%, transparent)}}.bg-bg{background-color:var(--bg)}.bg-primary{background-color:var(--primary)}.bg-primary-soft{background-color:var(--primary-soft)}.bg-sky-500\/15{background-color:#00a5ef26}@supports (color:color-mix(in lab, red, red)){.bg-sky-500\/15{background-color:color-mix(in oklab, var(--color-sky-500) 15%, transparent)}}.bg-surface{background-color:var(--surface)}.bg-surface-2{background-color:var(--surface-2)}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.bg-gradient-to-r{--tw-gradient-position:to right in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-muted{--tw-gradient-from:var(--text-muted);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.from-transparent{--tw-gradient-from:transparent;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.via-content{--tw-gradient-via:var(--text);--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-white\/5{--tw-gradient-via:#ffffff0d}@supports (color:color-mix(in lab, red, red)){.via-white\/5{--tw-gradient-via:color-mix(in oklab, var(--color-white) 5%, transparent)}}.via-white\/5{--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-white\/10{--tw-gradient-via:#ffffff1a}@supports (color:color-mix(in lab, red, red)){.via-white\/10{--tw-gradient-via:color-mix(in oklab, var(--color-white) 10%, transparent)}}.via-white\/10{--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-white\/25{--tw-gradient-via:#ffffff40}@supports (color:color-mix(in lab, red, red)){.via-white\/25{--tw-gradient-via:color-mix(in oklab, var(--color-white) 25%, transparent)}}.via-white\/25{--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.to-muted{--tw-gradient-to:var(--text-muted);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.to-transparent{--tw-gradient-to:transparent;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.bg-\[length\:200\%_100\%\]{background-size:200% 100%}.bg-clip-text{-webkit-background-clip:text;background-clip:text}.p-0{padding:0}.p-1{padding:var(--spacing)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.p-2\.5{padding:calc(var(--spacing) * 2.5)}.p-3{padding:calc(var(--spacing) * 3)}.px-0\.5{padding-inline:calc(var(--spacing) * .5)}.px-1{padding-inline:var(--spacing)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.px-7{padding-inline:calc(var(--spacing) * 7)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-10{padding-block:calc(var(--spacing) * 10)}.py-12{padding-block:calc(var(--spacing) * 12)}.pr-28{padding-right:calc(var(--spacing) * 28)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-heading{font-family:var(--font-heading)}.font-mono{font-family:var(--font-mono)}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.text-\[13px\]{font-size:13px}.text-\[14px\]{font-size:14px}.text-\[16px\]{font-size:16px}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-\[550\]{--tw-font-weight:550;font-weight:550}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.whitespace-pre{white-space:pre}.text-\[\#52b788\]{color:#52b788}.text-\[\#FC7070\]{color:#fc7070}.text-amber-400{color:var(--color-amber-400)}.text-amber-500{color:var(--color-amber-500)}.text-content{color:var(--text)}.text-green-500{color:var(--color-green-500)}.text-muted,.text-muted\/60{color:var(--text-muted)}@supports (color:color-mix(in lab, red, red)){.text-muted\/60{color:color-mix(in oklab, var(--text-muted) 60%, transparent)}}.text-primary{color:var(--primary)}.text-primary-contrast{color:var(--primary-contrast)}.text-red-400{color:var(--color-red-400)}.text-red-500{color:var(--color-red-500)}.text-sky-400{color:var(--color-sky-400)}.text-transparent{color:#0000}.text-white{color:var(--color-white)}.capitalize{text-transform:capitalize}.uppercase{text-transform:uppercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.underline{text-decoration-line:underline}.opacity-0{opacity:0}.opacity-70{opacity:.7}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-0{--tw-duration:0s;transition-duration:0s}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}@media (hover:hover){.group-hover\:translate-x-full:is(:where(.group):hover *){--tw-translate-x:100%;translate:var(--tw-translate-x) var(--tw-translate-y)}.group-hover\:\[animation\:text-shimmer_1\.2s_linear_1_forwards\]:is(:where(.group):hover *){animation:1.2s linear forwards text-shimmer}.group-hover\:text-transparent:is(:where(.group):hover *){color:#0000}.group-hover\:duration-\[1200ms\]:is(:where(.group):hover *){--tw-duration:1.2s;transition-duration:1.2s}.group-hover\/seg\:\[animation\:text-shimmer_1\.2s_linear_1_forwards\]:is(:where(.group\/seg):hover *){animation:1.2s linear forwards text-shimmer}.group-hover\/seg\:text-transparent:is(:where(.group\/seg):hover *){color:#0000}}.group-disabled\:hidden:is(:where(.group):disabled *){display:none}.placeholder\:text-muted::placeholder,.placeholder\:text-muted\/50::placeholder{color:var(--text-muted)}@supports (color:color-mix(in lab, red, red)){.placeholder\:text-muted\/50::placeholder{color:color-mix(in oklab, var(--text-muted) 50%, transparent)}}.last\:border-b-0:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.read-only\:cursor-default:read-only{cursor:default}.focus-within\:border-primary:focus-within,.focus-within\:border-primary\/60:focus-within{border-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.focus-within\:border-primary\/60:focus-within{border-color:color-mix(in oklab, var(--primary) 60%, transparent)}}.focus-within\:border-primary\/70:focus-within{border-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.focus-within\:border-primary\/70:focus-within{border-color:color-mix(in oklab, var(--primary) 70%, transparent)}}.focus-within\:ring-2:focus-within{--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)}.focus-within\:ring-primary\/15:focus-within{--tw-ring-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.focus-within\:ring-primary\/15:focus-within{--tw-ring-color:color-mix(in oklab, var(--primary) 15%, transparent)}}.focus-within\:ring-primary\/20:focus-within{--tw-ring-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.focus-within\:ring-primary\/20:focus-within{--tw-ring-color:color-mix(in oklab, var(--primary) 20%, transparent)}}@media (hover:hover){.hover\:border-primary\/70:hover{border-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.hover\:border-primary\/70:hover{border-color:color-mix(in oklab, var(--primary) 70%, transparent)}}.hover\:bg-\[\#e53935\]:hover{background-color:#e53935}.hover\:bg-border:hover{background-color:var(--border)}.hover\:bg-primary-hover:hover{background-color:var(--primary-hover)}.hover\:bg-surface-2:hover{background-color:var(--surface-2)}.hover\:text-content:hover{color:var(--text)}.hover\:text-primary-hover:hover{color:var(--primary-hover)}}.focus\:border-primary\/60:focus{border-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.focus\:border-primary\/60:focus{border-color:color-mix(in oklab, var(--primary) 60%, transparent)}}.focus\:ring-2:focus{--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)}.focus\:ring-primary\/20:focus{--tw-ring-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.focus\:ring-primary\/20:focus{--tw-ring-color:color-mix(in oklab, var(--primary) 20%, transparent)}}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:ring-2:focus-visible{--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)}.focus-visible\:ring-primary\/60:focus-visible{--tw-ring-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.focus-visible\:ring-primary\/60:focus-visible{--tw-ring-color:color-mix(in oklab, var(--primary) 60%, transparent)}}.active\:scale-105:active{--tw-scale-x:105%;--tw-scale-y:105%;--tw-scale-z:105%;scale:var(--tw-scale-x) var(--tw-scale-y)}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}.disabled\:opacity-60:disabled{opacity:.6}@media (prefers-reduced-motion:no-preference){.motion-safe\:animate-\[dropdown-expand_0\.2s_ease-out\]{animation:.2s ease-out dropdown-expand}.motion-safe\:animate-\[dropdown-expand_0\.18s_ease-in_reverse_forwards\]{animation:.18s ease-in reverse forwards dropdown-expand}.motion-safe\:animate-\[fade-in_0\.6s_ease-out_both\]{animation:.6s ease-out both fade-in}.motion-safe\:animate-\[widget-slide-in_180ms_ease-out\]{animation:.18s ease-out widget-slide-in}}@media (prefers-reduced-motion:reduce){.motion-reduce\:active\:scale-100:active{--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x) var(--tw-scale-y)}}@media (min-width:40rem){.sm\:inline{display:inline}}@media (min-width:48rem){.md\:col-start-auto{grid-column-start:auto}.md\:row-span-1{grid-row:span 1/span 1}.md\:inline{display:inline}.md\:grid-cols-\[1fr_auto\]{grid-template-columns:1fr auto}.md\:grid-cols-\[auto_1fr\]{grid-template-columns:auto 1fr}.md\:grid-cols-\[auto_1fr_1fr_auto\]{grid-template-columns:auto 1fr 1fr auto}.md\:grid-cols-\[minmax\(0\,0\.7fr\)_minmax\(0\,1fr\)\]{grid-template-columns:minmax(0,.7fr) minmax(0,1fr)}}.\[\&_button\]\:text-\[14px\] button{font-size:14px}}[data-theme=light]{--bg:#f2f4f7;--surface:#fff;--surface-2:#e7ebf3;--border:#d2d7df;--text:#0f1216;--text-muted:#4b5563;--primary:#7855ff;--primary-contrast:#fff}[data-theme=dark]{--bg:#16171d;--surface:#1f2028;--surface-2:#2a2c36;--border:#2e303a;--text:#f3f4f6;--text-muted:#9ca3af;--primary:#7855ff;--primary-contrast:#fff}[data-theme]{--primary-hover:var(--primary)}@supports (color:color-mix(in lab, red, red)){[data-theme]{--primary-hover:color-mix(in srgb, var(--primary) 86%, #000)}}[data-theme]{--primary-soft:var(--primary)}@supports (color:color-mix(in lab, red, red)){[data-theme]{--primary-soft:color-mix(in srgb, var(--primary) 16%, transparent)}}@keyframes shimmer{to{transform:translate(100%)}}@keyframes text-shimmer{0%{background-position:200%}to{background-position:-200%}}@keyframes dropdown-expand{0%{opacity:0;grid-template-rows:0fr}to{opacity:1;grid-template-rows:1fr}}@keyframes fade-in{0%{opacity:0}to{opacity:1}}@keyframes widget-slide-in{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}.token.comment,.token.prolog,.token.doctype,.token.cdata{color:var(--text-muted);font-style:italic}.token.punctuation{color:var(--text-muted)}.token.property,.token.tag,.token.symbol,.token.deleted{color:#7aa2f7}.token.number{color:#e5c07b}.token.boolean,.token.null,.token.keyword,.token.atrule,.token.important{color:var(--primary)}.token.string,.token.char,.token.attr-name,.token.attr-value,.token.regex,.token.inserted,.token.selector{color:#9ece6a}.token.operator,.token.entity,.token.url,.token.variable{color:var(--text)}.token.function,.token.class-name{color:#61afef}.token.builtin{color:#56b6c2}[data-theme=light] .token.property,[data-theme=light] .token.tag,[data-theme=light] .token.symbol,[data-theme=light] .token.deleted{color:#0550ae}[data-theme=light] .token.number{color:#953800}[data-theme=light] .token.string,[data-theme=light] .token.char,[data-theme=light] .token.attr-name,[data-theme=light] .token.attr-value,[data-theme=light] .token.regex,[data-theme=light] .token.inserted,[data-theme=light] .token.selector{color:#116329}[data-theme=light] .token.function,[data-theme=light] .token.class-name{color:#1f6feb}[data-theme=light] .token.builtin{color:#0e7490}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"<length-percentage>";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"<length-percentage>";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"<length-percentage>";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@keyframes spin{to{transform:rotate(360deg)}}