/** Which plan limit was hit; selects the modal's icon and copy via `resolveLimitCopy`. */ export type LimitKind = "record" | "automation" | "custom_modules" | "user" | "projects" | "tickets"; /** Fully controlled (isOpen/onClose only, no internal useDisclosure/autoOpen); closed prop list — modal size is fixed at "lg", not configurable. */ export interface LimitReachedModalProps { /** Controlled visibility; the modal renders nothing while false. */ isOpen: boolean; /** Called by the X button, Esc, overlay click and the Maybe later or Close button. */ onClose: () => void; /** Picks the icon, default title and default message; `user` gets a users icon, the rest a crown. */ kind: LimitKind; /** Inline usage line needs BOTH limit and used — either alone silently renders nothing. */ limit?: number | null; /** Amount already consumed; shown with `limit` as "X of Y used". */ used?: number | null; /** false hides the upgrade CTA and swaps in "contact your administrator" copy. */ canManageBilling: boolean; /** Clicking the CTA calls only this — it does not also call onClose. Close the modal yourself if upgrading should dismiss it. */ onUpgrade?: () => void; /** Overrides the kind's default heading. */ title?: string; /** Overrides the default body text, which also differs by `canManageBilling`. */ message?: string; /** Optional check-marked bullets listed under the message, e.g. what the next plan unlocks. */ features?: string[]; }