{
  "absorbed": [
    "Banner",
    "Callout"
  ],
  "example": "import { Alert, AlertTitle, AlertDescription } from \"@godxjp/ui/feedback\";\n\n<Alert tone=\"warning\">\n  <AlertTitle>3 件の打刻漏れがあります</AlertTitle>\n  <AlertDescription>本日中に確認してください。</AlertDescription>\n</Alert>",
  "group": "feedback",
  "importPath": "@godxjp/ui/feedback",
  "name": "Alert",
  "props": [
    {
      "defaultValue": "\"default\"",
      "description": "STRUCTURAL axis, orthogonal to `tone` (which owns colour + icon): \"default\" is the inline rounded card; \"banner\" is the full-bleed page/shell attention strip (square corners, page-gutter inset, actions wrap below 640px); \"callout\" is the aside INSIDE a document body — `role=\"note\"`, never a live region, `kind` picks the admonition. v32 folded the former `Banner` and `Callout` exports into these values.",
      "name": "variant",
      "type": "\"default\" | \"banner\" | \"callout\""
    },
    {
      "defaultValue": "\"note\"",
      "description": "`variant=\"callout\"` only. GitHub/Obsidian admonition preset; resolves the tone AND the leading glyph. A preset, not a second colour axis — `tone` and `icon` still override per instance. Ignored by the other variants.",
      "name": "kind",
      "type": "\"note\" | \"tip\" | \"important\" | \"warning\" | \"caution\""
    },
    {
      "description": "Renders an × dismiss button when provided.",
      "name": "onDismiss",
      "type": "() => void"
    },
    {
      "description": "Override or hide (false) the icon.",
      "name": "icon",
      "type": "LucideIcon | false"
    },
    {
      "description": "Semantic tone driving the colour + leading icon AND live-region politeness (\"destructive\"/\"warning\" announce assertively via role=\"alert\"; every other tone politely via role=\"status\"). Under `variant=\"callout\"` tone drives colour only — a callout is never a live region.",
      "name": "tone",
      "type": "\"default\" | \"success\" | \"warning\" | \"destructive\" | \"info\" | \"muted\" | \"neutral\""
    }
  ],
  "related": [
    "Toaster — use for transient, auto-dismissing feedback ('Record saved', 'Deleted'). Alert is for persistent page-scoped banners; Toaster is for fire-and-forget notifications triggered by toast() from sonner.",
    "AlertMutationFeedback — use when you want inline success/error feedback tightly coupled to a form mutation's state (renders inline below the submit button). Alert requires you to manage show/hide state yourself.",
    "DataState — use for full query lifecycle (loading skeleton + empty state + error) inside a data-fetching section. Alert.QueryError is the error sub-component DataState uses internally; prefer DataState when you also need the loading/empty states.",
    "ErrorSurface — a whole-page semantic exception state (403/404/5xx) that REPLACES the page. An `Alert` (any variant) annotates a page that still works.",
    "Prose — the typographic column a `variant=\"callout\"` normally sits inside; the callout's block margin is tuned to that rhythm.",
    "EmptyState — use for the zero-data case inside a list or table section, not for errors or warnings. Alert is for status messages; EmptyState is for the absence of data."
  ],
  "rules": [],
  "storyPath": "feedback/alert.tsx",
  "subParts": [
    "AlertActions",
    "AlertBase",
    "AlertContent",
    "AlertDescription",
    "AlertMutationFeedback",
    "AlertQueryError",
    "AlertTitle"
  ],
  "tagline": "Status message with a tone icon and optional dismiss, in three presentations: inline card, full-bleed page/shell strip (`variant=\"banner\"`), or a non-live aside inside a document (`variant=\"callout\"`, GitHub `> [!NOTE]`). Parts: Alert.Title/Description/Content/Actions/QueryError.",
  "usage": [
    "ANATOMY (positions are fixed — never re-lay-them-out): Alert is ONE horizontal row — a SINGLE leading tone icon at the inline-start (top-aligned to the first text line, auto-selected by `tone`, never two icons), then the text body (Title/Description), then `<Alert.Actions>` in a trailing-RIGHT column (≥sm), and the dismiss × pinned to the TOP-RIGHT corner (rendered by `onDismiss`). DON'T stack these vertically, DON'T make the action a full-width bar under the text, DON'T center the × at the bottom, DON'T add a second icon — that hand-rolled vertical banner is the #1 Alert mistake.",
    "DO compose text as `<Alert.Title>` + `<Alert.Description>` — they stack vertically inside the body (the Example below is canonical). When you add `<Alert.Actions>`, the body becomes a two-column grid (text | actions) at ≥sm; group multi-part text in `<Alert.Content>` so it occupies the text column as one block: `<Alert tone=\"destructive\"><Alert.Content><Alert.Title>Error</Alert.Title><Alert.Description>{msg}</Alert.Description></Alert.Content><Alert.Actions><Button …/></Alert.Actions></Alert>`.",
    "DO use `Alert.QueryError` (alias `AlertQueryError`) for TanStack Query / API failure surfaces — it already renders humanError(error), an i18n title, and an optional Retry button. Never hand-roll that pattern.",
    "`AlertMutationFeedback` props: `mutation`, `onRetry?`, `showRetry?` (default `true`), `pending?`, `ignoreValidationErrors?: boolean`, `className?`. `ignoreValidationErrors={true}` skips the alert for every error where `classifyQueryError(mutation.error).category === \"validation\"` (400/422). DEFAULT (omitted): skip a validation error only when rendered inside a `FormRoot`/`Form` whose `errors` bag holds at least one message (the fields show it, `<FormErrors />` shows unclaimed keys); outside such a form, or with an empty/absent bag, the alert renders. So DON'T hand-guard `{!isValidation && <AlertMutationFeedback …/>}` inside `FormRoot errors={…}` — a 422 is not drawn twice, and a 5xx still renders. Pass `ignoreValidationErrors={false}` to force the alert in such a form.",
    "DON'T pass raw action elements directly as top-level children of `<Alert>` without wrapping them in `<Alert.Actions>` — the layout slot only activates correctly via the `data-slot=\"alert-actions\"` wrapper.",
    "DON'T hand-roll a dismiss ✕ button — pass `onDismiss` to `<Alert>` and the component renders its own accessible dismiss button with `aria-label=\"Dismiss\"`. The `onDismiss` handler may return a Promise.",
    "DON'T suppress the icon with `icon={false}` unless there is a deliberate design reason; the icon is the primary a11y cue for sighted users since the root already carries `role=\"alert\"` for screen readers.",
    "BANNER (`variant=\"banner\"`): place it FULL-BLEED at the top of the surface it warns about — directly under the Topbar inside AppShell's children for shell-wide attention (past-due subscription, active support session), or as the first child of a page. Its inline inset defaults to the page gutter (--space-page-active-x) and its geometry is owned by the `--banner-*` tokens; never fake a strip with `className` overrides. At most ONE per surface.",
    "CALLOUT (`variant=\"callout\"`): for content that is PART of the document being read — a docs admonition, a CMS note, a policy caveat. It renders `role=\"note\"` and never announces. Map Markdown `[!NOTE]`/`[!TIP]`/`[!IMPORTANT]`/`[!WARNING]`/`[!CAUTION]` straight onto `kind`. DON'T pass `onDismiss` (prose is not dismissed) and DON'T use a callout for something that just HAPPENED — that is the default or banner variant, which announce.",
    "LIVE OR NOT (gh#1271): static, unchanging guidance → `variant=\"callout\"` (not a live region, `role=\"note\"`); `role=\"alert\"`/`role=\"status\"` (the default and banner variants) are for messages that appear in response to something — a failed save, a sync that finished. A hint that is on the page when it loads is not a status message (WCAG 4.1.3), so it must not announce on every render.",
    "DO NOT use `Alert` for transient ephemeral feedback (e.g. 'saved successfully'). Use `toast()` from sonner + `<Toaster>` for that. `Alert` is for persistent, page-scoped banners that stay visible until the user acts or dismisses."
  ],
  "useCases": [
    "Page-level error banner after a form submission fails server-side validation — `tone=\"destructive\"` with `Alert.Title` summarising the error and `Alert.Description` listing field issues, paired with `onDismiss` so the user can clear it.",
    "Inline warning at the top of an accounting invoice list when the OAuth token for the MF sync is about to expire — `tone=\"warning\"` with an `Alert.Actions` containing a 'Reconnect' Button.",
    "Success confirmation banner rendered after a bulk-import job completes and the user returns to the list page — `tone=\"success\"` with `Alert.Description` showing the record count imported.",
    "TanStack Query data-fetch failure inside a Card body — use `<Alert.QueryError error={error} onRetry={refetch} />` instead of writing a custom error state.",
    "Informational notice at the top of a settings page when a feature is in beta or requires a plan upgrade — `tone=\"info\"` with a short description and an `Alert.Actions` 'Learn more' link.",
    "Past-due subscription strip across the console shell — `variant=\"banner\" tone=\"warning\"` with an `Alert.Actions` \"お支払い方法を更新\" Button, rendered above the page slot until billing recovers.",
    "Docs/handbook admonition inside a prose column — `variant=\"callout\" kind=\"tip\"`; a destructive-consequence note beside a runbook step is `kind=\"caution\"`, still silent on load.",
    "Dismissible billing-overdue notice at the top of the dashboard — `tone=\"destructive\"` with `onDismiss` that sets a session flag so it does not reappear until the next login."
  ]
}
