diff --git a/.cursor/rules/alerts.mdc b/.cursor/rules/alerts.mdc new file mode 100644 index 0000000..dfd2dc5 --- /dev/null +++ b/.cursor/rules/alerts.mdc @@ -0,0 +1,48 @@ +--- +description: Unified Alert (toast/banner) for app notifications — Figma + drift prevention +globs: app/**/*.tsx, stories/modals/Alert.stories.js, tests/components/Alert.test.tsx +alwaysApply: false +--- + +# Alerts and notifications + +## Source of truth + +- **Figma:** [Community Rule System — Modal / Alert](https://www.figma.com/design/agv0VBLiBlcnSAaiAORgPR/Community-Rule-System?node-id=6351-14646) (node **6351-14646**). +- **Code:** `app/components/modals/Alert` — default export `Alert` from `Alert.container.tsx` (Figma docstring on the container). + +## When to use `Alert` + +Use **`Alert`** for **app-level, section-level, and shell-level** success, warning, error, and neutral status messages that should read as a designed system surface (not body copy alone). + +Do **not** recreate the same job with ad-hoc UI: bordered `

`, free-standing `role="alert"` blocks, or raw `text-[var(--color-border-default-utility-negative)]` paragraphs for product messaging. + +## Props (lowercase in code; match Figma intent) + +| Concern | Prop | Notes | +| --- | --- | --- | +| Layout | `type` | `toast` — bottom accent bar, top rounded corners; `banner` — full rounded block, inline or stacked. | +| Intent | `status` | `default` \| `positive` \| `warning` \| `danger`. | +| Density | `size` | `s` \| `m` (Figma S/M). Typography and padding are implemented inside `Alert.container.tsx` — do not fork spacing per call site. | +| Copy | `title`, `description?` | Required title; optional description when `hasBodyText` is true. | +| Icon | `hasLeadingIcon?` | Default `true`. | +| Body | `hasBodyText?` | Default `true`; set `false` for title-only. | +| Dismiss | `onClose?`, `hasTrailingIcon?` | Close control shows only when `onClose` is provided **and** `hasTrailingIcon` is not `false`. Omit `onClose` for non-dismissible messages. | + +Valid enum slices for Storybook / guards: `ALERT_*_OPTIONS` in `lib/propNormalization.ts`. + +## Choosing toast vs banner + +- **`toast`** — transient edge / bottom emphasis (e.g. completed flow), strong bottom border accent. +- **`banner`** — rounded block; for **page / shell / modal** messaging, mount inside a **`fixed`** (or equivalent) overlay wrapper with `pointer-events-none` on the outer layer and `pointer-events-auto` on the alert so layout chrome does not reflow when the message appears (see `CreateFlowLayoutClient` `topBanners`, profile overlays, `LoginForm`, `PostLoginDraftTransfer`). + +## Exemptions (do not force `Alert`) + +1. **Single-field validation** under a control — keep `TextInput` / `TextArea` `error` and helper text (e.g. invalid email on the login form) unless design explicitly moves that line into `Alert`. +2. **Marketing layout** — `HeroBanner`, `ContentBanner` are not system alerts. +3. **Landmarks** — `role="banner"` on headers/nav is not the `Alert` “banner” type. +4. **A11y-only live regions** — e.g. tooltip / incrementer `aria-live` for widget state, not product notifications. + +## Copy + +All user-visible strings go through **`messages/`** and `useTranslation` / message modules per `localization.mdc`. diff --git a/.cursor/rules/coding-guidelines.mdc b/.cursor/rules/coding-guidelines.mdc index edd317f..3119783 100644 --- a/.cursor/rules/coding-guidelines.mdc +++ b/.cursor/rules/coding-guidelines.mdc @@ -3,7 +3,7 @@ description: Behavioral guidelines to reduce common LLM coding mistakes. Use whe alwaysApply: true --- -# Karpathy behavioral guidelines +# Coding behavioral guidelines Behavioral guidelines to reduce common LLM coding mistakes. Merge with project-specific instructions as needed. diff --git a/.cursor/rules/create-flow.mdc b/.cursor/rules/create-flow.mdc index fb76949..caa10b8 100644 --- a/.cursor/rules/create-flow.mdc +++ b/.cursor/rules/create-flow.mdc @@ -31,7 +31,7 @@ Reach for these before writing new markup: | Mid-paragraph "expand / see all" link button | `app/components/buttons/InlineTextButton` | | Help-icon + label above a control | `app/components/utility/InputLabel` (`helpIcon` prop) | | Toggle chip (dim-but-clickable) | `Chip` with `state="Disabled" disabled={false}` | -| Card-click → structured creation modal | `Create` with `backdropVariant="loginYellow"` | +| Card-click → structured creation modal | `Create` with `backdropVariant="blurredYellow"` | If a screen grows a 2nd inline copy of any pattern above, **extract a shared component** rather than duplicate. Local section components inside a screen diff --git a/.cursor/rules/routes.mdc b/.cursor/rules/routes.mdc index 1f9d9dd..9d253ed 100644 --- a/.cursor/rules/routes.mdc +++ b/.cursor/rules/routes.mdc @@ -15,7 +15,7 @@ the file tree without affecting URLs. | Group | URL surface | Audience | Chrome | |---|---|---|---| | `app/(marketing)/` | `/`, `/learn`, `/blog`, `/templates`, future public pages | Public, indexable | TopNav (via root) + marketing `