---
version: alpha
name: Petal Whisper
description: "Rounded UI for AI assistants: rose actions on cool grey-blue neutrals, red-orange errors, and short bouncy motion that keeps text readable."
colors:
  background: "#f6f8fb"
  foreground: "#151a26"
  card: "#ffffff"
  card-foreground: "#151a26"
  popover: "#ffffff"
  popover-foreground: "#151a26"
  primary: "#c92a5f"
  primary-foreground: "#ffffff"
  secondary: "#edf0f5"
  secondary-foreground: "#242b3a"
  muted: "#edf0f5"
  muted-foreground: "#4b5568"
  accent: "#ffe3ec"
  accent-foreground: "#631433"
  destructive: "#c2410c"
  destructive-foreground: "#ffffff"
  success: "#0c6748"
  success-foreground: "#ffffff"
  warning: "#ffe08a"
  warning-foreground: "#422e02"
  border: "#dde2eb"
  input: "#c3cad7"
  ring: "#e6457a"
  dark-background: "#151a26"
  dark-foreground: "#f6f8fb"
  dark-card: "#242b3a"
  dark-card-foreground: "#f6f8fb"
  dark-popover: "#242b3a"
  dark-popover-foreground: "#f6f8fb"
  dark-primary: "#f76d99"
  dark-primary-foreground: "#400a20"
  dark-secondary: "#353e4f"
  dark-secondary-foreground: "#edf0f5"
  dark-muted: "#353e4f"
  dark-muted-foreground: "#c3cad7"
  dark-accent: "#631433"
  dark-accent-foreground: "#ffe3ec"
  dark-destructive: "#f97a4a"
  dark-destructive-foreground: "#3a1308"
  dark-success: "#3fbf88"
  dark-success-foreground: "#021f17"
  dark-warning: "#e0ad26"
  dark-warning-foreground: "#2a1c01"
  dark-border: "#353e4f"
  dark-input: "#4b5568"
  dark-ring: "#f76d99"
typography:
  display-lg:
    fontFamily: Geist
    fontSize: 48px
    fontWeight: 700
    lineHeight: 1.08
    letterSpacing: -0.03em
  display-md:
    fontFamily: Geist
    fontSize: 38px
    fontWeight: 700
    lineHeight: 1.12
    letterSpacing: -0.025em
  heading-lg:
    fontFamily: Geist
    fontSize: 30px
    fontWeight: 600
    lineHeight: 1.2
    letterSpacing: -0.02em
  heading-md:
    fontFamily: Geist
    fontSize: 24px
    fontWeight: 600
    lineHeight: 1.25
    letterSpacing: -0.015em
  heading-sm:
    fontFamily: Geist
    fontSize: 20px
    fontWeight: 600
    lineHeight: 1.35
    letterSpacing: -0.01em
  body-lg:
    fontFamily: Geist
    fontSize: 18px
    fontWeight: 400
    lineHeight: 1.6
  body-md:
    fontFamily: Geist
    fontSize: 16px
    fontWeight: 400
    lineHeight: 1.6
  body-sm:
    fontFamily: Geist
    fontSize: 14px
    fontWeight: 400
    lineHeight: 1.55
  label:
    fontFamily: Geist
    fontSize: 14px
    fontWeight: 500
    lineHeight: 1.3
    letterSpacing: 0.005em
  caption:
    fontFamily: Geist
    fontSize: 12px
    fontWeight: 500
    lineHeight: 1.45
    letterSpacing: 0.01em
  code:
    fontFamily: Geist Mono
    fontSize: 14px
    fontWeight: 400
    lineHeight: 1.6
rounded:
  sm: 6px
  md: 12px
  lg: 16px
  xl: 24px
  full: 9999px
spacing:
  xs: 4px
  sm: 8px
  md: 16px
  lg: 24px
  xl: 32px
  2xl: 48px
  3xl: 64px
components:
  button-primary:
    backgroundColor: "{colors.primary}"
    textColor: "{colors.primary-foreground}"
    typography: "{typography.label}"
    rounded: "{rounded.full}"
    padding: 0 20px
    height: 40px
  button-secondary:
    backgroundColor: "{colors.secondary}"
    textColor: "{colors.secondary-foreground}"
    typography: "{typography.label}"
    rounded: "{rounded.full}"
    padding: 0 20px
    height: 40px
  button-destructive:
    backgroundColor: "{colors.destructive}"
    textColor: "{colors.destructive-foreground}"
    typography: "{typography.label}"
    rounded: "{rounded.full}"
    padding: 0 20px
    height: 40px
  input:
    backgroundColor: "{colors.background}"
    textColor: "{colors.foreground}"
    typography: "{typography.body-sm}"
    rounded: "{rounded.md}"
    padding: 0 16px
    height: 44px
  card:
    backgroundColor: "{colors.card}"
    textColor: "{colors.card-foreground}"
    rounded: "{rounded.lg}"
    padding: 24px
  popover:
    backgroundColor: "{colors.popover}"
    textColor: "{colors.popover-foreground}"
    rounded: "{rounded.lg}"
    padding: 12px
  helper-text:
    backgroundColor: "{colors.background}"
    textColor: "{colors.muted-foreground}"
    typography: "{typography.body-sm}"
  table-row-alt:
    backgroundColor: "{colors.muted}"
    textColor: "{colors.muted-foreground}"
    typography: "{typography.body-sm}"
    height: 44px
  badge:
    backgroundColor: "{colors.accent}"
    textColor: "{colors.accent-foreground}"
    typography: "{typography.caption}"
    rounded: "{rounded.full}"
    padding: 0 8px
    height: 24px
  badge-success:
    backgroundColor: "{colors.success}"
    textColor: "{colors.success-foreground}"
    typography: "{typography.caption}"
    rounded: "{rounded.full}"
    padding: 0 8px
    height: 24px
  badge-warning:
    backgroundColor: "{colors.warning}"
    textColor: "{colors.warning-foreground}"
    typography: "{typography.caption}"
    rounded: "{rounded.full}"
    padding: 0 8px
    height: 24px
  badge-destructive:
    backgroundColor: "{colors.destructive}"
    textColor: "{colors.destructive-foreground}"
    typography: "{typography.caption}"
    rounded: "{rounded.full}"
    padding: 0 8px
    height: 24px
  button-primary-dark:
    backgroundColor: "{colors.dark-primary}"
    textColor: "{colors.dark-primary-foreground}"
    typography: "{typography.label}"
    rounded: "{rounded.full}"
    padding: 0 20px
    height: 40px
  button-secondary-dark:
    backgroundColor: "{colors.dark-secondary}"
    textColor: "{colors.dark-secondary-foreground}"
    typography: "{typography.label}"
    rounded: "{rounded.full}"
    padding: 0 20px
    height: 40px
  button-destructive-dark:
    backgroundColor: "{colors.dark-destructive}"
    textColor: "{colors.dark-destructive-foreground}"
    typography: "{typography.label}"
    rounded: "{rounded.full}"
    padding: 0 20px
    height: 40px
  input-dark:
    backgroundColor: "{colors.dark-background}"
    textColor: "{colors.dark-foreground}"
    typography: "{typography.body-sm}"
    rounded: "{rounded.md}"
    padding: 0 16px
    height: 44px
  card-dark:
    backgroundColor: "{colors.dark-card}"
    textColor: "{colors.dark-card-foreground}"
    rounded: "{rounded.lg}"
    padding: 24px
  popover-dark:
    backgroundColor: "{colors.dark-popover}"
    textColor: "{colors.dark-popover-foreground}"
    rounded: "{rounded.lg}"
    padding: 12px
  helper-text-dark:
    backgroundColor: "{colors.dark-background}"
    textColor: "{colors.dark-muted-foreground}"
    typography: "{typography.body-sm}"
  table-row-alt-dark:
    backgroundColor: "{colors.dark-muted}"
    textColor: "{colors.dark-muted-foreground}"
    typography: "{typography.body-sm}"
    height: 44px
  badge-dark:
    backgroundColor: "{colors.dark-accent}"
    textColor: "{colors.dark-accent-foreground}"
    typography: "{typography.caption}"
    rounded: "{rounded.full}"
    padding: 0 8px
    height: 24px
  badge-success-dark:
    backgroundColor: "{colors.dark-success}"
    textColor: "{colors.dark-success-foreground}"
    typography: "{typography.caption}"
    rounded: "{rounded.full}"
    padding: 0 8px
    height: 24px
  badge-warning-dark:
    backgroundColor: "{colors.dark-warning}"
    textColor: "{colors.dark-warning-foreground}"
    typography: "{typography.caption}"
    rounded: "{rounded.full}"
    padding: 0 8px
    height: 24px
  badge-destructive-dark:
    backgroundColor: "{colors.dark-destructive}"
    textColor: "{colors.dark-destructive-foreground}"
    typography: "{typography.caption}"
    rounded: "{rounded.full}"
    padding: 0 8px
    height: 24px
---

# Petal Whisper

## Overview

Petal Whisper is for conversational AI products where people should feel welcomed rather than tested. A saturated rose primary sits on cool grey-blue neutrals, so the interface feels lively while long chat threads stay calm. The system expresses playfulness through pill shapes, rounded surfaces and short motion. Every text pairing holds at least 4.5:1 contrast in both modes, and most hold at least 5:1.

Moods: playful, friendly, bouncy, approachable. Built for: ai-assistant, productivity, consumer-apps. Density: comfortable.

Every color has a light value and a dark value. Tokens named `dark-*` are the dark-mode counterparts of the token with the same role name.

## Colors

Brand is a cool rose. brand.600 (#c92a5f) is the light-mode primary at 5.2:1 with white text, and brand.400 (#f76d99) is the dark-mode primary at 6.2:1 on neutral.950. Neutrals carry a deliberate blue tint (hue about 255), from neutral.50 #f6f8fb to neutral.950 #151a26, and each step darkens evenly with no grey dip in the middle. Danger moved further toward orange: danger.600 is #c2410c (5.2:1 with white) and danger.400 is #f97a4a in dark mode. This keeps primary and destructive more than 18 ΔE2000 apart in both modes, so an error never reads as a brand moment. Success is a minty green (success.700 #0c6748, 6.9:1 with white). Warning is a warm amber (warning.200 surface with warning.900 text). Both have chroma levels close to rose's, so they sit beside it without competing. The light ring is brand.500 (3.6:1 on background). The dark ring is brand.400.

- **Primary** `#c92a5f` / dark `#f76d99`: the single action color. Primary buttons, links, focus ring.
- **Background / Foreground** `#f6f8fb` / dark `#151a26` on `#151a26` / dark `#f6f8fb`: page surface and body text.
- **Card** `#ffffff` / dark `#242b3a`: raised surfaces.
- **Secondary** `#edf0f5` / dark `#353e4f`: secondary buttons and quiet controls.
- **Muted** `#edf0f5` / dark `#353e4f` with **muted-foreground** `#4b5568` / dark `#c3cad7`: helper text, table stripes, disabled-looking surfaces.
- **Accent** `#ffe3ec` / dark `#631433`: highlights, selected rows, badges.
- **Destructive** `#c2410c` / dark `#f97a4a`, **Success** `#0c6748` / dark `#3fbf88`, **Warning** `#ffe08a` / dark `#e0ad26`: status only, always paired with an icon or label.
- **Border** `#dde2eb` / dark `#353e4f`, **Input** `#c3cad7` / dark `#4b5568`, **Ring** `#e6457a` / dark `#f76d99`.

All text/background pairs above pass WCAG AA (4.5:1) in both modes; this is checked automatically at build time.

## Typography

Geist is the only text family, from greeting to chat bubble. Geist Mono is used for code, tokens and identifiers. The scale follows a ratio of about 1.25 from the 16px body: 20, 24, 30, 38, 48. Letter spacing tightens as size grows, from -0.01em at heading-sm (20px) to -0.03em at display-lg (48px). Display sizes use weights 600 to 700, which Geist ships. Body text uses weight 400 with a line height of 1.6 at body-md and body-lg so long model responses read comfortably. label uses 500. caption uses 500 at 12px with +0.01em tracking.

- Display: **Geist** (fallback system-ui, sans-serif)
- Interface: **Geist** (fallback system-ui, sans-serif)
- Mono: **Geist Mono** (fallback ui-monospace, monospace)

| Token | Font | Size | Line height | Weight |
|---|---|---|---|---|
| display-lg | Geist | 48px | 1.08 | 700 |
| display-md | Geist | 38px | 1.12 | 700 |
| heading-lg | Geist | 30px | 1.2 | 600 |
| heading-md | Geist | 24px | 1.25 | 600 |
| heading-sm | Geist | 20px | 1.35 | 600 |
| body-lg | Geist | 18px | 1.6 | 400 |
| body-md | Geist | 16px | 1.6 | 400 |
| body-sm | Geist | 14px | 1.55 | 400 |
| label | Geist | 14px | 1.3 | 500 |
| caption | Geist | 12px | 1.45 | 500 |
| code | Geist Mono | 14px | 1.6 | 400 |

## Layout

Comfortable density on a 4px base grid. Chat columns cap at 760px, which keeps body-md lines near 75 characters. Sidebars and settings panels use space.4 to space.6 (16px to 24px) of internal padding. Message groups are separated by space.6.

Spacing uses a 4px base: xs = 4px, sm = 8px, md = 16px, lg = 24px, xl = 32px, 2xl = 48px, 3xl = 64px.

## Elevation & Depth

In light mode, cards and inputs sit on #ffffff with a 1px border (neutral.200) and shadow.sm. Popovers and command palettes use shadow.md. Dialogs use shadow.lg. All shadows are tinted with neutral.950 rather than black. Dark mode builds elevation from tone instead of shadow. The background is neutral.950, while cards and popovers are lifted one step to neutral.900 with a neutral.800 border.

- sm: `0 1px 2px rgba(21, 26, 38, 0.06), 0 1px 1px rgba(21, 26, 38, 0.04)`
- md: `0 6px 16px -4px rgba(21, 26, 38, 0.14)`
- lg: `0 18px 44px -10px rgba(21, 26, 38, 0.24)`

## Shapes

Rounding is generous. Inputs use radius.md (12px). Cards and message bubbles use radius.lg (16px). Hero and empty-state surfaces use radius.xl (24px). Small chips and tooltips use radius.sm (6px). Buttons and badges use radius.full so interactive elements read as tactile pills.

Radius scale: sm 6px, md 12px, lg 16px, xl 24px, full 9999px.

## Components

Components ending in `-dark` are the dark-mode versions. Button: 40px tall, 20px horizontal padding, label type. Input: 44px tall with a 1px input-colored border; focus shows a 2px ring in the ring color. Card: 24px padding, 1px border, sm shadow. Badge: pill, caption type.

## Do's and Don'ts

- **Do:** Use primary (brand.600 light, brand.400 dark) for exactly one main action per view, such as Send or Start chat. Render other actions as secondary or ghost buttons.
- **Do:** Build buttons at 40px height with radius.full, label typography and fontWeight 600. Keep inputs at 44px height with radius.md.
- **Do:** Show focus with a 2px ring token and a 2px offset on every interactive element. This uses brand.500 in light mode and brand.400 in dark mode.
- **Do:** Use display-lg (48px) and display-md (38px) only for greetings and empty-state headlines. Use heading-sm (20px) for message group titles.
- **Do:** Render AI responses in body-md (16px, line height 1.6) within a 760px column. Set code blocks in Geist Mono with code typography on the muted surface.
- **Do:** Pair every success, warning and destructive color with an icon or text label so status never relies on color alone.
- **Don't:** Don't use primary or any brand step for errors or destructive confirmations. Use destructive (danger.600 light, danger.400 dark).
- **Don't:** Don't put long body text on accent (brand.100 light, brand.900 dark). Reserve accent for selected conversations, highlights and active nav items.
- **Don't:** Don't put shadow.md or shadow.lg on cards or message bubbles. Use shadow.md for popovers and command palettes, and shadow.lg for dialogs. In dark mode, show elevation with the card token (neutral.900) instead of shadow.
- **Don't:** Don't use neutral.600 or lighter for text on the light muted surface (it drops below 4.5:1). Use muted-foreground (neutral.700).
- **Don't:** Don't use pure black for text or for dark-mode surfaces. Use neutral.950 for both.
- **Don't:** Don't apply bounce or overshoot to text. Keep motion under 300ms, and disable overshoot when prefers-reduced-motion is set.
