Design system component catalog from the ds-bundle.
## Design Tokens
### Colors
- **NEVER use hardcoded hex colors** - Always use semantic tokens from `globals.css`
- **Default palette is enterprise**: Primary `--color-primary` (#5C9000), Secondary `--color-secondary` (#007399), Accent `--color-accent` (#CC0058). Use vibrant aliases only when needed.
- Background: `--color-deep-space` (#0d1117)
- Surface: `--color-slate` (#1c2128)
- Text: `--color-steel` (#8b9aad) for secondary text
### Borders
- Default 1px; use `--border-default` or `--border-subtle`. Avoid 2px except focus rings. Prefer `border border-[var(--border-default)]`.
### Sizing
- Use rem for spacing, typography, radius, shadows. Use px only for 1px borders.
**Usage in Tailwind**:
```tsx
// ✅ Correct
<div className="bg-primary text-white">
<div className="text-steel bg-slate">
<div className="bg-(--color-primary-alpha-10)"> // Opacity tokens
// ❌ Wrong
<div className="bg-primary">
<div style={{ color: '#8b9aad' }}>
<div className="bg-primary/10"> // Use opacity tokens instead
```
**Opacity Tokens**:
- Use CSS custom properties for rgba patterns: `--color-primary-alpha-10`, `--color-secondary-alpha-15`, etc.
- Available opacity levels: 06, 08, 10, 12, 15, 20, 25, 30, 35, 40, 48
- RGB values available: `--color-primary-rgb`, `--color-secondary-rgb`, `--color-accent-rgb`
**Shadow Tokens & Utilities**:
- Use shadow tokens: `--shadow-primary-lg`, `--shadow-primary-hover`, `--shadow-accent-hover`
- Use Tailwind utility classes: `shadow-primary-lg`, `shadow-primary-hover`, `shadow-accent-hover`
- Never hardcode box-shadow values - always use tokens or utility classes
```tsx
// ✅ Correct
<div className="shadow-primary-lg">
<button className="shadow-accent-hover hover:shadow-primary-hover">
// ❌ Wrong
<div style={{ boxShadow: '0 12px 40px 0 rgba(115, 180, 0, 0.15)' }}>
```
### Typography
- Base body text: `text-body` (20px / 1.25rem)
- Headings: Use `Heading` component with `level` prop (1-6)
- Font families: `--font-heading` (General Sans), `--font-body` (General Sans), `--font-mono` (JetBrains Mono)
**Usage**:
```tsx
// ✅ Correct
<Heading level={1} gradient shimmer>Title</Heading>
<Text size="body" color="primary">Body text</Text>
// ❌ Wrong
<h1 className="text-4xl">Title</h1>
<p style={{ fontSize: '20px' }}>Body text</p>
```
### Spacing
- Use 8dp grid system - all spacing should be multiples of 8px
- Semantic spacing: `gap-xs` (8px), `gap-sm` (16px), `gap-md` (24px), `gap-lg` (32px), `gap-xl` (40px)
- Tailwind spacing: Use `space-*` utilities (space-2 = 8px, space-4 = 16px, etc.)
**Usage**:
```tsx
// ✅ Correct
<div className="space-y-4 gap-md">
<div className="p-6"> // 24px = 3 * 8px
// ❌ Wrong
<div className="space-y-[13px]"> // Not a multiple of 8
```
### Logo
- **Always use the Reshape logo** for headers, presentations, demos, and marketing materials.
- **Canonical URL**: `https://www.reshapex.com/images/logos/reshape-logo.svg`
- **Same-origin**: `/images/logos/reshape-logo.svg` (same asset).
- Include `alt="ReshapeX"` for accessibility.## Component Patterns
### Import Pattern
```tsx
// ✅ Correct - Import from ui index
import { Button, Card, CardContent, Heading, Text } from "@/components/ui";
// ❌ Wrong - Direct imports
import Button from "@/components/ui/Button";
```
### Button Component
```tsx
// ✅ Correct
<Button variant="primary" size="md" href="/path">
Click me
</Button>
// Variants: primary, secondary, destructive, outline, ghost, dark
// Sizes: sm, md (default), lg, icon
```
### Card Component
```tsx
// ✅ Correct
<Card variant="elevated">
<CardHeader>
<CardTitle>Title</CardTitle>
</CardHeader>
<CardContent>Content</CardContent>
</Card>
// Variants: default, light, elevated (default), bordered
```## Styling Guidelines
### Tailwind + Semantic Tokens
- Use Tailwind utilities with semantic tokens
- Prefer Tailwind classes over inline styles
- Use `cn()` utility for conditional classes
```tsx
// ✅ Correct
import { cn } from '@/lib/utils'
<div className={cn("bg-slate p-6", isActive && "border-primary")}>
// ❌ Wrong
<div className="bg-slate" style={{ padding: '24px' }}>
```## Common Mistakes to Avoid 1. ❌ **Hardcoded colors** - Always use design tokens 2. ❌ **Inline styles** - Use Tailwind classes 3. ❌ **Wrong spacing values** - Use 8dp grid (multiples of 8px) 4. ❌ **Direct component imports** - Import from `@/components/ui` 5. ❌ **Using `any` type** - Use proper TypeScript types
## See Also - [Component Patterns Rule](../component-patterns/RULE.md) - Component usage examples - [Accessibility Rule](../accessibility/RULE.md) - WCAG AAA compliance requirements - [TypeScript Rule](../typescript/RULE.md) - Type safety for components - [Component Patterns Rule](../component-patterns/RULE.md) - Component usage patterns - [Code Architecture Rule](../code-architecture/RULE.md) - UI-first design principles
## Presentations > **Roles**: Designer (owns locked Figma template layers) | Editor (changes text, swaps images, embeds video in Figma Slides) --- ### Slide Mode System Dark slides use the **marketing palette** (`#73B400`, `#00D9FF`, `#FF006E`). Light slides use the **enterprise palette** (`#5C9000`, `#005C90`, `#90005C`). Content type determines mode — editors do not choose. **NEVER mix**: Marketing palette colors may not be used as accents on light slides. Enterprise palette colors may not be the primary accent on dark slides. | Mode | HTML Background | Text Color | Palette | | ----- | --------------- | ---------- | ---------- | | Dark | `transparent` | `#FFFFFF` | Marketing | | Light | `#FFFFFF` | `#0D1117` | Enterprise | **Dark slide content types**: Title, section break, stat callout, quote, hero image, closing/Q&A, any brand or impact moment **Light slide content types**: Dense data tables, financial charts, partner/customer logos, process diagrams, appendix slides --- ### HTML Generation Rules Every slide HTML fragment must: 1. **No wrappers** — never include `<html>`, `<body>`, `<header>`, `<footer>`, or `<nav>` tags 2. **Background** — dark slides: `background: transparent` | light slides: `background: #FFFFFF` 3. **Hex values only** — Figma does NOT resolve CSS custom properties; `var(--color-primary)` arrives as a literal string. Use hex values from the tables below. 4. **Canvas size** — content zone: `width: 1920px; height: 900px` (full slide is 1920×1080; template owns ~90px header + ~90px footer) 5. **Padding** — `padding: 80px 120px; box-sizing: border-box` 6. **Font** — `font-family: Inter, -apple-system, BlinkMacSystemFont, sans-serif` 7. **px values** — use `px` for all type sizes, not `rem` or Tailwind classes (Figma import strips class names) ```html <!-- RESHAPE SLIDE CONTENT ZONE — 1920x900px --> <!-- DO NOT include <html>, <body>, <header>, <footer>, <nav> --> <div style=" width: 1920px; height: 900px; background: transparent; /* #FFFFFF for light slides */ padding: 80px 120px; box-sizing: border-box; font-family: Inter, -apple-system, BlinkMacSystemFont, sans-serif; color: #FFFFFF; /* #0D1117 for light slides */ position: relative; overflow: hidden; " > <!-- SLIDE CONTENT HERE --> </div> ``` --- ### CSS Reference — Dark Slides | Token | Hex Value | | -------------- | ---------------------------------------------------------------------- | | background | `transparent` | | textPrimary | `#FFFFFF` | | textBody | `#E5E9EC` | | textSubtle | `#A0AEB8` | | textMuted | `#8B9AAD` | | electricGreen | `#73B400` | | cyberBlue | `#00D9FF` | | magenta | `#FF006E` | | voltYellow | `#FFE500` | | divider | `#1C2128` | | cardSurface | `#1C2128` | | gradientHero | `linear-gradient(135deg, #73B400 0%, #00D9FF 100%)` | | gradientCyber | `linear-gradient(135deg, #00D9FF 0%, #FF006E 100%)` | | gradientNeural | `linear-gradient(135deg, #73B400 0%, #FFE500 100%)` | | gradientFull | `linear-gradient(135deg, #73B400 0%, #00D9FF 50%, #FF006E 100%)` | | imageOverlay | `linear-gradient(to right, rgba(13,17,23,0.95) 40%, transparent 100%)` | ### CSS Reference — Light Slides | Token | Hex Value | | ----------------- | --------------------------------------------------- | | background | `#FFFFFF` | | textPrimary | `#0D1117` | | textBody | `#1C2128` | | textSubtle | `#8B9AAD` | | enterpriseGreen | `#5C9000` | | enterpriseBlue | `#005C90` | | enterpriseMagenta | `#90005C` | | enterpriseViolet | `#340090` | | divider | `#E5E9EC` | | cardSurface | `#F5F7FA` | | gradientAccent | `linear-gradient(135deg, #5C9000 0%, #005C90 100%)` | --- ### Typography Scale (px — not rem) | Role | Size | Weight | Line Height | Letter Spacing | | --------- | ----- | ------ | ----------- | -------------- | | title | 88px | 800 | 1.05 | -0.02em | | subtitle | 36px | 400 | 1.30 | 0 | | h2 | 64px | 700 | 1.10 | -0.01em | | h3 | 44px | 700 | 1.15 | -0.01em | | body | 26px | 400 | 1.50 | 0 | | caption | 20px | 400 | 1.40 | 0.01em | | stat | 112px | 900 | 1.00 | -0.03em | | statLabel | 22px | 600 | 1.30 | 0.04em | | code | 22px | 400 | 1.60 | 0 | | eyebrow | 16px | 600 | 1.20 | 0.10em | **Dark mode colors**: title `#FFFFFF`, body `#E5E9EC`, caption `#A0AEB8`, stat `gradient or #00D9FF` **Light mode colors**: title `#0D1117`, body `#1C2128`, caption `#8B9AAD`, stat `#005C90` --- ### Title Accent Rule Titles may use a **single** accent color on **1–3 words** that carry the semantic weight. Accents mark arguments, not style. Use hex inline styles — class names are stripped on Figma import. ```html <!-- Correct — accent marks the statistic (the argument) --> Your factory floor <span style="color: #73B400">wastes 23%</span> of capacity <!-- Wrong — decorative, no semantic reason --> <span>Your</span> factory <span>floor</span> wastes <span>23%</span> <!-- Wrong — two accent colors in one title --> <span style="color: #73B400">Faster</span> and <span style="color: #FF006E">Smarter</span> <!-- Wrong — marketing color on a light slide --> Revenue grew <span style="color: #73B400">40%</span> ← use #5C9000 on light slides ``` **Dark slides**: allowed accent colors `#73B400`, `#00D9FF`, `#FF006E`, or `linear-gradient(135deg, #73B400, #00D9FF)` **Light slides**: allowed accent colors `#5C9000`, `#005C90`, `#90005C` Non-accented title words: always `#FFFFFF` on dark, `#0D1117` on light — never a lighter tint of the accent. --- ### Slide Grid Anchor Points ``` Canvas: 1920 × 1080px Content zone: 1920 × 900px (header 90px top, footer 90px bottom) Margin: 120px all sides Headline Y: 80px from content zone top Body Y: 240px from content zone top Stat center Y: 200px from content zone top Left column X: 120px Right column X: 1080px (two-column layouts) ``` --- ### Slide Templates | ID | Label | Default Mode | Supports Light | Editor Zones | | ------------------ | --------------------- | ------------ | -------------- | -------------------------------------------------- | | `title` | Title Slide | dark | No | presentation title, subtitle, date, presenter name | | `content` | Content Slide | dark | Yes | heading, body copy, image (swap), video embed | | `stat-callout` | Stat Callout | dark | No | stat number, stat label, context sentence | | `icon-grid` | Icon Grid | dark | Yes | icon (swap), label, description | | `section-break` | Section Break | dark | No | section title, section subtitle | | `quote` | Quote Slide | either | Yes | quote text, attribution name, attribution title | | `two-column` | Two-Column Content | either | Yes | heading, left body, right body, image (swap) | | `data-viz` | Data Visualization | light | Yes | heading, chart data, footnote | | `hero-image` | Full-Bleed Hero Image | dark | No | headline, subhead, image (swap) | | `before-after` | Before / After | either | Yes | heading, before/after labels and content | | `process-timeline` | Process / Timeline | either | Yes | heading, step labels ×4–6, step descriptions | | `team` | Team | dark | Yes | photo (swap), name, title, bio | | `qa` | Q&A / Closing | dark | No | heading, contact information | Logo is always a locked designer layer in template header/footer — never in editor zones. --- ### Transition Standards | Context | Type | Duration | | --------------------- | ------------- | ----------------- | | Default (all slides) | Dissolve | 300ms | | Into section break | Push (left) | 400ms | | Within-slide elements | Smart Animate | 200ms ease-in-out | **Prohibited**: Cube, 3D flip, Zoom, Flip, Whirl --- ### Color Choreography | Deck Section | Mode | Accent | | ------------ | ----- | -------------------------- | | Opening | Dark | `#73B400` Electric Green | | Problem | Dark | `#00D9FF` Cyber Blue | | Solution | Dark | `gradientHero` AI Energy | | Proof | Light | `#5C9000` Enterprise Green | | Closing | Dark | `#FF006E` Magenta | Dark slides perform. Light slides prove. --- ### Data Visualization **Dark slide series order**: `#73B400` → `#00D9FF` → `#5C9000` → `#005C90` **Light slide series order**: `#5C9000` → `#005C90` → `#340090` → `#90005C` `#FF006E` (Magenta) is NEVER a data series — reads as alert/error. Dark chart styling: grid lines `#1C2128`, axis labels `#8B9AAD`, data labels `#FFFFFF` Light chart styling: grid lines `#E5E9EC`, axis labels `#8B9AAD`, data labels `#0D1117` **Avoid**: 3D charts, pie charts (>2 segments), stacked area (>2 series), radar/spider --- ### Deck Typology Quick Reference | Type | Max Words/Slide | Slide Count | Light Slide % | | ------------ | --------------- | ----------- | ------------- | | Sales | 30 | 10–18 | 20–30% | | Board | 50 | 12–20 | 40–60% | | Product Demo | 60 | 8–20 | 30–40% | | Conference | 15 | 20–50 | 0–10% | | Internal | 60 | 5–25 | 20–40% | --- ### Narrative Arc | Position | Role | Template | Mode | | -------- | ---------------- | ---------------- | ------ | | 1 | Opening | title | dark | | 2–3 | The problem | content | dark | | 4 | Cost of inaction | stat-callout | dark | | 5–7 | The solution | content | dark | | 8–9 | How it works | process-timeline | either | | 10–12 | Proof / results | data-viz | light | | 13 | Why us | content | dark | | 14 | Call to action | qa | dark | | 15+ | Appendix | content | light | No deck shorter than 8 slides. No deck longer than 20 for a 30-minute meeting. --- ### Quality Rubric Hard Fails - ❌ Contains `<header>`, `<footer>`, `<nav>`, `<html>`, or `<body>` tags - ❌ Dark slide HTML sets background to `#0D1117` (must be `transparent`) - ❌ Light slide HTML sets background to `transparent` (must be `#FFFFFF`) - ❌ Marketing palette color (`#73B400`, `#00D9FF`, `#FF006E`) used as accent on a light slide - ❌ Enterprise palette color used as primary accent on a dark slide - ❌ More than 3 brand colors in the content zone - ❌ More than 1 accent color in a single title - ❌ Title accent words have no stated semantic reason - ❌ Speaker notes absent or verbatim repetition of slide text - ❌ CSS custom property (`var(--...)`) used in slide HTML — must use hex values --- ### Anti-Patterns - ✗ NEVER include `<header>`, `<footer>`, or `<nav>` — Figma template owns these - ✗ NEVER use `var(--...)` CSS custom properties — Figma does not resolve them - ✗ NEVER wrap in `<html>` or `<body>` tags — import_html expects a fragment - ✗ NEVER use marketing palette on light slides — neon on white is garish - ✗ NEVER set `#0D1117` background in dark slide HTML — template sets it - ✗ NEVER use `#FF006E` Magenta as a chart data series — reads as alert - ✗ NEVER use a white background for stat, title, or section break slides - ✗ NEVER use gradient text on light slides - ✗ NEVER box-contain images on dark backgrounds - ✗ NEVER use color logos on dark slides — white SVG only - ✗ NEVER write speaker notes that repeat the slide - ✗ NEVER use prohibited transitions (Cube, 3D flip, Zoom, Flip, Whirl) - ✗ NEVER use 3D charts, pie charts (>2 segments), or radar charts