From 7618e0af45e6e480e63e5803d3951dfcfbf09e79 Mon Sep 17 00:00:00 2001 From: Jayash Tripathy <76092296+JayashTripathy@users.noreply.github.com> Date: Sat, 6 Dec 2025 20:37:32 +0530 Subject: [PATCH] chore: added brief agents.md and story for new design system --- .gitignore | 2 - .../design-system-philosophy.stories.tsx | 397 +++++++++++ packages/tailwind-config/AGENTS.md | 630 ++++++++++++++++++ 3 files changed, 1027 insertions(+), 2 deletions(-) create mode 100644 packages/propel/src/design-system/design-system-philosophy.stories.tsx create mode 100644 packages/tailwind-config/AGENTS.md diff --git a/.gitignore b/.gitignore index f0093a0e68..e2e6441ba3 100644 --- a/.gitignore +++ b/.gitignore @@ -105,10 +105,8 @@ CLAUDE.md build/ .react-router/ -AGENTS.md build/ .react-router/ -AGENTS.md temp/ scripts/ diff --git a/packages/propel/src/design-system/design-system-philosophy.stories.tsx b/packages/propel/src/design-system/design-system-philosophy.stories.tsx new file mode 100644 index 0000000000..386620645e --- /dev/null +++ b/packages/propel/src/design-system/design-system-philosophy.stories.tsx @@ -0,0 +1,397 @@ +import React from "react"; +import type { Meta, StoryObj } from "@storybook/react-vite"; + +const meta = { + title: "Design System/Philosophy", + parameters: { + layout: "fullscreen", + docs: { + description: { + component: ` +# Design System Philosophy + +Reusable, composable Storybook stories that demonstrate Canvas, Surface, and Layer concepts. + +Key concepts and rules are preserved, but the implementation is componentized for DRYness and clarity. + `, + }, + }, + }, + tags: ["autodocs"], +} satisfies Meta; + +export default meta; +export type Story = StoryObj; + +/* ----------------------------- + Reusable UI building blocks + -----------------------------*/ + +type ContainerProps = { + children?: React.ReactNode; + className?: string; +}; + +const DemoRoot: React.FC = ({ children, className = "" }) => ( +
{children}
+); + +const Info: React.FC<{ title: string; children?: React.ReactNode; tone?: "info" | "warn" }> = ({ + title, + children, + tone = "info", +}) => ( +
+

{title}

+
{children}
+
+); + +const Surface: React.FC = ({ children, className = "bg-surface-1 rounded-md p-6" }) => ( +
{children}
+); + +const Layer: React.FC = ({ + children, + className = "bg-layer-1 hover:bg-layer-1-hover rounded-md p-4", +}) =>
{children}
; + +/* Small helpers to keep stories concise */ +const TwoColGrid: React.FC<{ children: React.ReactNode }> = ({ children }) => ( +
{children}
+); + +/* ----------------------------- + Stories (using the building blocks) + -----------------------------*/ + +export const ApplicationRoot: Story = { + render: () => ( + + + This is the bg-canvas - the application-level background. It should only appear{" "} + once in your entire application at the root level. + + + +

Page Content (bg-surface-1)

+

Pages use surfaces, not canvas. This is a typical page layout.

+
+
+ ), +}; + +export const SurfaceSiblings: Story = { + render: () => ( + + + Surfaces are siblings, not nested. + + + + +

Surface 1

+

This is bg-surface-1 - a primary surface

+
+ + +

Surface 2

+

This is bg-surface-2 - a secondary surface (sibling to surface-1)

+
+
+
+ ), +}; + +export const LayerStacking: Story = { + render: () => ( + + Layers stack to create depth: Surface → Layer 1 → Layer 2 → Layer 3 + + +

Surface 1

+ + +
Layer 1 (First level of depth)
+

Hover over me to see the hover state

+ + +
Layer 2 (Second level)
+

Nested within Layer 1

+ + +

Layer 3 (Third level)

+

Deepest nesting level

+
+
+
+
+
+ ), +}; + +export const SurfaceLayerAssociation: Story = { + render: () => ( + + + Each surface should use its corresponding layer: surface-1 → layer-1, surface-2 → layer-2 + + + + +

Surface 1

+ +
Layer 1
+

Correctly using layer-1 with surface-1

+
+
+ + +

Surface 2

+ +
Layer 2
+

Correctly using layer-2 with surface-2

+
+
+
+
+ ), +}; + +export const ModalException: Story = { + render: () => ( + + + Modals exist on a different plane, so they can use surfaces even when there's a surface + below + + + +

Main Page Content

+

This is the main page using bg-surface-1

+
+ +
+
+
+

Modal Dialog

+

+ This modal uses bg-surface-1 even though the page below also uses bg-surface-1. This is allowed because + they're on different planes. +

+ + +

Modal content can use layers as normal

+
+
+
+ + ), +}; + +export const CardListPattern: Story = { + render: () => ( + + Common pattern: Surface containing multiple layer-1 cards + + +

Task List

+
+ {[1, 2, 3].map((item) => ( + +
Task {item}
+

This is a task card using bg-layer-1 with hover state

+
+ ))} +
+
+
+ ), +}; + +export const SidebarLayoutPattern: Story = { + render: () => ( + + Sidebar and main content are both part of the same surface + + + + +
+

Main Content

+ +

Content card using layer-1

+
+
+
+
+ ), +}; + +export const StateVariants: Story = { + render: () => ( + + Demonstrating hover, active, and selected states + + +
+ +
Hover State
+

Hover over me to see bg-layer-1-hover

+
+ +
+
Active State
+

Using bg-layer-1-active (pressed/active)

+
+ +
+
Selected State
+

Using bg-layer-1-selected (when selected)

+
+
+
+
+ ), +}; + +export const TextColorHierarchy: Story = { + render: () => ( + + Semantic text colors for different importance levels + + +
+

Primary Text

+

Secondary text for descriptions and supporting content

+

Tertiary text for labels and metadata

+ +
+
+
+ ), +}; + +export const CompleteExample: Story = { + render: () => ( + + A realistic dashboard layout using all design system concepts + +
+
+

Dashboard

+
+
+ +
+ {[ + { label: "Total Users", value: "1,234" }, + { label: "Active Projects", value: "42" }, + { label: "Completed Tasks", value: "856" }, + ].map((stat, idx) => ( + + +

{stat.label}

+

{stat.value}

+
+
+ ))} +
+ +
+ +

Recent Activity

+
+ {[1, 2, 3].map((item) => ( + +

Activity {item}

+

Description of the activity

+
+ ))} +
+
+ + +

Quick Actions

+
+ {["Create Project", "Invite Team", "View Reports"].map((action) => ( + +

{action}

+
+ ))} +
+
+
+
+ ), +}; + +export const CommonMistakes: Story = { + render: () => ( + + + These examples show incorrect usage patterns + + +
+
+

❌ Mistake 1: Nested Surfaces (Same Plane)

+ +

Surface 1

+
+

Surface 2 nested inside Surface 1 - WRONG!

+
+
+

+ ✅ Fix: Use bg-layer-1 for nested elements, or make them sibling surfaces +

+
+ +
+

❌ Mistake 2: Wrong Layer-Surface Association

+ +

Surface 1

+
+

Using layer-2 with surface-1 - WRONG!

+
+
+

✅ Fix: Use bg-layer-1 with bg-surface-1

+
+ +
+

❌ Mistake 3: Mismatched Hover State

+ +
+

bg-layer-1 with hover:bg-layer-2-hover - WRONG!

+
+
+

✅ Fix: Use bg-layer-1 hover:bg-layer-1-hover

+
+ +
+

❌ Mistake 4: Canvas for Pages

+
+

Using bg-canvas for a page or component - WRONG!

+
+

+ ✅ Fix: Canvas should only be at application root. Use bg-surface-1 for pages +

+
+
+
+ ), +}; diff --git a/packages/tailwind-config/AGENTS.md b/packages/tailwind-config/AGENTS.md new file mode 100644 index 0000000000..68f7ca7181 --- /dev/null +++ b/packages/tailwind-config/AGENTS.md @@ -0,0 +1,630 @@ +# Design System Philosophy Guide + +## Overview + +This guide explains the semantic design system philosophy for building consistent, maintainable UIs. The system is built on three core concepts: **Canvas**, **Surface**, and **Layer**. + +## Core Concepts + +### 1. Canvas (`bg-canvas`) + +**What it is**: The application-level background that serves as the foundation for all content. The canvas is the **entire application background**, not individual pages. There is only **one canvas** in the entire application, used at the root level. + +**When to use**: + +- **Only at the application root** - the single root container that wraps the entire application +- The main application background (not page backgrounds) + +**When NOT to use**: + +- ❌ Page-level backgrounds +- ❌ Nested containers +- ❌ Cards or components +- ❌ Modals or dropdowns +- ❌ Sidebars or panels +- ❌ Anywhere else in the application + +**Critical Rule**: Canvas should only appear **once** in your entire application - at the root level. All pages, routes, and components sit on top of this single canvas. + +**Example**: + +```tsx +// ✅ Correct: Canvas at application root (only place it should be) +// App.tsx or root layout +
+ {/* All application content goes here */} + + } /> + +
; + +// ✅ Correct: Pages use surfaces, not canvas +function Page() { + return
{/* Page content */}
; +} + +// ❌ Wrong: Canvas used for a page +function Page() { + return
{/* Don't use canvas here */}
; +} + +// ❌ Wrong: Canvas used for a card +
{/* Card content */}
; +``` + +### 2. Surface (`bg-surface-1`, `bg-surface-2`, `bg-surface-3`) + +**What it is**: Top-level containers that sit directly on the canvas. Surfaces never overlap each other - they are siblings in the layout hierarchy. + +**When to use**: + +- Main content areas +- Sections of a page +- Primary containers +- Panels that sit side-by-side + +**Surface hierarchy**: + +- `bg-surface-1`: Primary surface (most common) +- `bg-surface-2`: Secondary surface (for variation) +- `bg-surface-3`: Tertiary surface (rare, for special cases) + +**Rules**: + +- Surfaces are **siblings**, not nested (in the same plane) +- Each surface should use its corresponding layer for nested elements +- Surfaces provide the base for stacking layers + +**Exception - Different Planes**: + +- Modals, overlays, and popovers exist on a **different plane** (different z-index/stacking context) +- In these cases, it's acceptable to use a surface even when there's a surface below +- This is because they are visually and functionally separate from the underlying content + +**Example**: + +```tsx +// ✅ Correct: Surfaces as siblings +
+
+ {/* Main content area */} +
+
+ {/* Secondary content area - sibling, not nested */} +
+
+ +// ✅ Correct: Page with header and main (same surface) +
+
+ {/* Header is part of the surface, not a separate surface */} +
+
+ {/* Main is part of the surface, not a separate surface */} +
+
+ +// ❌ Wrong: Surface nested in surface (same plane) +
+
+ {/* This breaks the philosophy */} +
+
+ +// ✅ Correct: Modal on different plane +
+ {/* Main page content */} +
+ Page content +
+ + {/* Modal overlay - different plane */} +
+
+
+ {/* Modal can use surface-1 even though page uses surface-1 */} + Modal content +
+
+
+``` + +### 3. Layer (`bg-layer-1`, `bg-layer-2`, `bg-layer-3`) + +**What it is**: Stacking layers that create depth within a surface. Layers stack on top of each other in a specific order. + +**When to use**: + +- Cards within a surface +- Group headers +- Nested containers +- Dropdowns and modals +- Sidebars +- Any element that needs to appear "on top" of a surface + +**Layer hierarchy**: + +- `bg-layer-1`: First layer (closest to surface) +- `bg-layer-2`: Second layer (on top of layer-1) +- `bg-layer-3`: Third layer (on top of layer-2) + +**Critical Rule - Layer-to-Surface Association**: + +- `bg-surface-1` → use `bg-layer-1` for nested elements +- `bg-surface-2` → use `bg-layer-2` for nested elements +- `bg-surface-3` → use `bg-layer-3` for nested elements + +**Example**: + +```tsx +// ✅ Correct: Surface-1 with layer-1 +
+
+ Card content +
+
+ +// ✅ Correct: Surface-2 with layer-2 +
+
+ Card content +
+
+ +// ❌ Wrong: Surface-1 with layer-2 +
+
+ {/* Wrong layer for this surface */} +
+
+``` + +## Stacking Layers + +### How to Stack Layers + +Layers stack in order: surface → layer-1 → layer-2 → layer-3 + +**Pattern**: + +``` +Canvas + └── Surface + └── Layer 1 (first level of depth) + └── Layer 2 (second level of depth) + └── Layer 3 (third level of depth) +``` + +**Example - Proper Stacking**: + +```tsx +// ✅ Correct: Proper layer stacking +
+ {/* Layer 1: Card */} +
+

Card Title

+ + {/* Layer 2: Nested section */} +
+ Nested content + {/* Layer 3: Deeply nested */} +
Deep content
+
+
+
+``` + +**When to use each layer**: + +- **Layer 1**: Most common - cards, headers, primary nested elements +- **Layer 2**: Secondary depth - nested cards, sub-sections +- **Layer 3**: Deep nesting - rarely needed, for complex hierarchies + +## State Variants + +### Hover States + +**Critical Rule**: Hover must always match the base background layer. + +**Pattern**: `bg-layer-X hover:bg-layer-X-hover` + +**Examples**: + +```tsx +// ✅ Correct: Matching hover +
+ Hoverable element +
+ +
+ Hoverable element +
+ +// ❌ Wrong: Mismatched hover +
+ {/* Never do this */} +
+``` + +### Active States + +Use `-active` variants when an element is in an active/pressed state. + +```tsx +// ✅ Correct: Active state + +``` + +### Selected States + +Use `-selected` variants only when there's actual selection logic. + +```tsx +// ✅ Correct: Selected state with logic +
+ Selectable item +
+ +// ✅ Correct: With data attribute +
+ Selectable item +
+``` + +## Common Patterns + +### Pattern 1: Application Root Layout + +```tsx +// ✅ Correct: Application root (only place for canvas) +// App.tsx or root layout +
+ + } /> + } /> + +
; + +// ✅ Correct: Individual page structure +function HomePage() { + return ( +
+ {/* Header - part of the page surface, uses layer for depth */} +
+
Header content
+
+ + {/* Main content - part of the page surface */} +
+
Content card
+
+
+ ); +} +``` + +### Pattern 2: Card with Nested Elements + +```tsx +// ✅ Correct: Card with proper layering +
+
+

Card Title

+ + {/* Nested section */} +
+

Nested content

+
+
+
+``` + +### Pattern 3: Dropdown/Modal + +```tsx +// ✅ Correct: Modal structure (different plane exception) +function PageWithModal() { + return ( +
+ {/* Main page content */} +
Page content
+ + {/* Modal - different plane, can use surface even with surface below */} + {isModalOpen && ( +
+
+
+
Modal content
+
+
+ )} +
+ ); +} +``` + +### Pattern 4: Sidebar Layout + +```tsx +// ✅ Correct: Sidebar with main content (page level, not app root) +// Both sidebar and main are siblings on the same surface +function DashboardPage() { + return ( +
+ {/* Sidebar - part of the page surface */} + + + {/* Main content - part of the page surface */} +
+
Main content
+
+
+ ); +} +``` + +### Pattern 5: List with Items + +```tsx +// ✅ Correct: List structure +
+
List item 1
+
List item 2
+
List item 3
+
+``` + +### Pattern 6: Form with Inputs + +```tsx +// ✅ Correct: Form structure +
+
+
+ + +
+ + +
+
+``` + +## Decision Tree + +### When to use Canvas? + +``` +Is this the root container of the entire application? +(Only one place in the whole app) +├─ YES → Use bg-canvas (application root only) +└─ NO → Continue to Surface decision +``` + +### When to use Surface? + +``` +Is this a top-level container that sits on canvas? +AND +Is it a sibling to other containers (not nested)? +OR +Is this a modal/overlay on a different plane (z-index)? +├─ YES → Use bg-surface-1 (or surface-2/3 for variation) +└─ NO → Continue to Layer decision +``` + +### When to use Layer? + +``` +Is this nested within a surface? +├─ YES → Use bg-layer-1 (or layer-2/3 for deeper nesting) +│ Match layer number to surface number +└─ NO → Re-evaluate: Should this be a surface? +``` + +## Text Colors + +Use semantic text colors that match the hierarchy: + +- `text-primary`: Main text, headings, important content +- `text-secondary`: Secondary text, descriptions +- `text-tertiary`: Tertiary text, labels, metadata +- `text-placeholder`: Placeholder text, hints + +**Example**: + +```tsx +
+

Title

+

Description text

+ Metadata + +
+``` + +## Border Colors + +Use semantic border colors: + +- `border-subtle`: Subtle borders, dividers +- `border-subtle-1`: Slightly more visible borders +- `border-strong`: Strong borders, emphasis +- `border-strong-1`: Very strong borders + +**Example**: + +```tsx +
+
Section with divider
+
+``` + +## Common Mistakes to Avoid + +### ❌ Mistake 1: Canvas for Pages or Cards + +```tsx +// ❌ Wrong: Canvas used for a page +function Page() { + return
Page content
; +} + +// ❌ Wrong: Canvas used for a card +
Card content
; + +// ✅ Correct: Pages use surfaces +function Page() { + return ( +
+
Card content
+
+ ); +} +``` + +### ❌ Mistake 2: Nested Surfaces (Same Plane) + +```tsx +// ❌ Wrong: Nested surfaces in same plane +
+
+ Nested surface +
+
+ +// ✅ Correct: Use layer instead +
+
+ Nested layer +
+
+ +// ✅ Correct: Exception - Modal on different plane +
+
Page content
+
+
Modal (different plane)
+
+
+``` + +### ❌ Mistake 3: Wrong Layer for Surface + +```tsx +// ❌ Wrong: surface-1 with layer-2 +
+
+ Content +
+
+ +// ✅ Correct: surface-1 with layer-1 +
+
+ Content +
+
+``` + +### ❌ Mistake 4: Mismatched Hover + +```tsx +// ❌ Wrong +
+ Content +
+ +// ✅ Correct +
+ Content +
+``` + +### ❌ Mistake 5: Missing Hover Prefix + +```tsx +// ❌ Wrong +
+ Content +
+ +// ✅ Correct +
+ Content +
+``` + +## Best Practices + +1. **Canvas is Application Root Only**: Canvas should only appear once in your entire application - at the root level (App.tsx or root layout). All pages use surfaces, not canvas. + +2. **Use Surfaces for Pages and Top-Level Containers**: Surfaces are siblings, not nested (except modals/overlays on different planes) + +3. **Match Layers to Surfaces**: surface-1 → layer-1, surface-2 → layer-2, etc. + +4. **Stack Layers Properly**: Use layer-1 first, then layer-2, then layer-3 as needed + +5. **Always Match Hover States**: If base is `bg-layer-X`, hover must be `hover:bg-layer-X-hover` + +6. **Use Semantic Text Colors**: Match text color to importance (primary, secondary, tertiary, placeholder) + +7. **Keep It Simple**: Don't over-nest. Most components only need layer-1 + +8. **Test Visual Hierarchy**: Ensure the stacking creates clear visual depth + +## Quick Reference + +### Hierarchy Structure + +``` +Canvas (one per page) + └── Surface 1 (top-level container) + └── Layer 1 (first level of depth) + └── Layer 2 (second level) + └── Layer 3 (third level) +``` + +### Common Combinations + +- Application Root: `bg-canvas` (only one place in entire app) +- Single Surface Page: `bg-surface-1` → `bg-layer-1` +- Multiple Surfaces Page: Grid of `bg-surface-1` (or `bg-surface-2`) as siblings +- Card: `bg-surface-1` → `bg-layer-1 hover:bg-layer-1-hover` +- Nested Card: `bg-surface-1` → `bg-layer-1` → `bg-layer-2` +- Sidebar Layout: `bg-surface-1` (sidebar) + `bg-surface-1` (main) - both siblings + +### State Variants + +- Hover: `bg-layer-X hover:bg-layer-X-hover` +- Active: `bg-layer-X-active` (when pressed/active) +- Selected: `bg-layer-X-selected` (when selected) + +## Alignment Checklist + +When reviewing components, ensure: + +- [ ] Canvas is only used at the application root (one place in entire app) +- [ ] Pages use surfaces, not canvas +- [ ] Surfaces are siblings, not nested (except modals/overlays on different planes) +- [ ] Layers match their surface (surface-1 → layer-1) +- [ ] Hover states match base layers +- [ ] Layers stack properly (1 → 2 → 3) +- [ ] Text colors are semantic (primary, secondary, tertiary, placeholder) +- [ ] Borders use semantic colors (subtle, strong) +- [ ] No unnecessary nesting +- [ ] Visual hierarchy is clear +- [ ] State variants are used correctly +- [ ] Modals/overlays use surfaces (exception to nesting rule)