@affinda/react 0.0.23 → 0.0.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -26,13 +26,13 @@ defineCustomElements();
26
26
  ### 2. Use Components
27
27
 
28
28
  ```tsx
29
- import { Button, Navbar, NavItem, Logo } from '@affinda/react';
29
+ import { Button, Navbar, NavItem } from '@affinda/react';
30
30
 
31
31
  function App() {
32
32
  return (
33
33
  <div>
34
+ {/* Navbar displays the default Affinda logo automatically */}
34
35
  <Navbar>
35
- <Logo slot="logo" />
36
36
  <div slot="start">
37
37
  <NavItem href="/products">Products</NavItem>
38
38
  </div>
@@ -70,6 +70,15 @@ Affinda components use the **NeuSans** font family. To get the authentic Affinda
70
70
 
71
71
  ## Usage
72
72
 
73
+ > ⚠️ **Theme Container Requirement:** Always wrap your components in a theme-providing container like `Section`, `HeroSection`, or `Card`. These containers establish theme context via CSS custom properties that child components (Heading, Text, Button, etc.) consume for their colors.
74
+ >
75
+ > ```tsx
76
+ > <Section theme="white">
77
+ > <Heading level="1">Title</Heading>
78
+ > <Text>Content with proper colors</Text>
79
+ > </Section>
80
+ > ```
81
+
73
82
  ### Import Components
74
83
 
75
84
  All components are available with or without the `Af` prefix:
@@ -84,89 +93,107 @@ import { Button, Heading, TypographyLockup } from '@affinda/react';
84
93
 
85
94
  ### Available Components
86
95
 
87
- **Layout & Structure:**
88
- - **HeroSection** / AfHeroSection - Hero sections for marketing pages
89
- - **Section** / AfSection - Page sections with consistent spacing
90
- - **Container** / AfContainer - Layout containers with max-width
91
- - **AspectRatio** / AfAspectRatio - Maintain aspect ratios for media
96
+ Components are organized by complexity level. **Always compose from these levels** — don't write custom HTML/CSS for layouts that components already handle.
92
97
 
93
- **Navigation:**
94
- - **Navbar** / AfNavbar - Navigation bar with mobile hamburger menu
95
- - **NavItem** / AfNavItem - Navigation items
98
+ #### Atoms (Basic Building Blocks)
96
99
 
97
- **Typography:**
100
+ - **Button** / AfButton - Primary buttons with variants and icons
101
+ - **IconButton** / AfIconButton - Icon-only buttons
98
102
  - **Heading** / AfHeading - Typography headings (H1-H6) with theme support
99
103
  - **Text** / AfText - Body text components with theme support
100
- - **TypographyLockup** / AfTypographyLockup - Composite heading + text + button layouts
101
-
102
- **Buttons:**
103
- - **Button** / AfButton - Primary buttons with variants, icons, and dark background support
104
- - **ButtonGroup** / AfButtonGroup - Group multiple buttons together
105
- - **IconButton** / AfIconButton - Icon-only buttons
106
-
107
- **Cards & Content:**
108
- - **Card** / AfCard - Content cards with optional backgrounds and photo variants
104
+ - **Tag** / AfTag - Categorization labels with sand and light variants
105
+ - **Section** / AfSection - Page sections with consistent spacing and themes ⭐ *provides theme context*
106
+ - **Card** / AfCard - Content cards with optional backgrounds and photo variants ⭐ *provides theme context*
107
+ - **Container** / AfContainer - Layout containers with max-width
108
+ - **IconBox** / AfIconBox - Themed container for displaying an icon with rounded background
109
+ - **Logo** / AfLogo - Affinda logo component
110
+ - **LogoWell** / AfLogoWell - Rounded container for client logos
111
+ - **AspectRatio** / AfAspectRatio - Maintain aspect ratios for media
109
112
  - **ColorSwatch** / AfColorSwatch - Display color swatches
110
113
 
111
- **Social Proof:**
112
- - **ClientCarousel** / AfClientCarousel - Infinite scrolling carousel for client logos
113
- - **LogoWell** / AfLogoWell - Rounded container for client logos
114
+ #### Molecules (Composed from Atoms)
115
+
116
+ - **ButtonGroup** / AfButtonGroup - Group multiple buttons together
117
+ - **TypographyLockup** / AfTypographyLockup - Composite heading + text + button layouts
118
+ - **IconText** / AfIconText - IconBox + TypographyLockup for feature items with icons
119
+ - **FeatureCard** / AfFeatureCard - Card + image + TypographyLockup for feature showcase
120
+ - **IllustratedCard** / AfIllustratedCard - Card + illustration slot
121
+ - **NavItem** / AfNavItem - Navigation items
122
+ - **NavCard** / AfNavCard - Navigation card with icon and description
114
123
  - **Testimonial** / AfTestimonial - Customer testimonials with background images, stats, and quotes
115
- - **TestimonialCarousel** / AfTestimonialCarousel - Carousel for sliding between multiple testimonials
116
124
  - **TestimonialStat** / AfTestimonialStat - Individual statistics within testimonials
117
-
118
- **Feature Showcase:**
119
- - **FeatureAccordion** / AfFeatureAccordion - Expandable accordion with auto-cycling timer and image display
120
- - **CtaSection** / AfCtaSection - Call-to-action section with illustration and buttons
121
-
122
- **Brand:**
123
- - **Logo** / AfLogo - Affinda logo component
124
-
125
- **Decorative:**
126
- - **PaperclipDecoration** - Decorative paperclip vector for hero sections
127
-
128
- **Footer:**
129
- - **Footer** / AfFooter - Slot-based footer layout component
130
125
  - **FooterColumn** / AfFooterColumn - Navigation column for footer
131
126
  - **FooterLink** / AfFooterLink - Styled link for footer navigation
132
127
  - **SocialLink** / AfSocialLink - Circular social media icon link
133
128
  - **ContactItem** / AfContactItem - Label/value pair for contact info
129
+ - **PaperclipDecoration** - Decorative paperclip vector for hero sections
130
+
131
+ #### Organisms (Page Sections)
132
+
133
+ - **Navbar** / AfNavbar - Navigation bar with mobile hamburger menu
134
+ - **HeroSection** / AfHeroSection - Hero sections for marketing pages ⭐ *provides theme context*
135
+ - **FeatureGrid** / AfFeatureGrid - Responsive CSS grid container for feature cards/items
136
+ - **FeatureAccordion** / AfFeatureAccordion - Expandable accordion with auto-cycling timer
137
+ - **GridCallout** / AfGridCallout - Image + heading + IconText grid for feature sections
138
+ - **SplitSection** / AfSplitSection - Two-column layouts with image and content
139
+ - **ClientCarousel** / AfClientCarousel - Infinite scrolling carousel for client logos
140
+ - **TestimonialCarousel** / AfTestimonialCarousel - Carousel for sliding between testimonials
141
+ - **InPageBanner** / AfInPageBanner - Call-to-action banner card with illustration ⭐ *provides theme context*
142
+ - **Footer** / AfFooter - Slot-based footer layout component
134
143
 
135
144
  ## Quick Start Components
136
145
 
137
146
  ### HeroSection
138
147
 
139
- The hero section component makes it easy to create marketing page heroes with consistent styling.
148
+ The hero section component makes it easy to create marketing page heroes with consistent styling. It uses **TypographyLockup** internally to handle proper spacing and layout of heading, description, and buttons.
140
149
 
141
150
  ```tsx
142
- import { HeroSection, Heading, Text, Button, PaperclipDecoration } from '@affinda/react';
151
+ import { HeroSection, Heading, Text, Button, ButtonGroup, PaperclipDecoration } from '@affinda/react';
143
152
 
144
- <HeroSection variant="dark" withDecoration={true} minHeight="60vh">
153
+ <HeroSection
154
+ theme="inkwell"
155
+ withDecoration={true}
156
+ minHeight="60vh"
157
+ headingSize={1}
158
+ textAlignment="center"
159
+ buttonAlignment="horizontal"
160
+ >
145
161
  {/* Position the paperclip decoration - adjust bottom/right values as needed */}
146
162
  <PaperclipDecoration
147
163
  slot="decoration"
148
164
  style={{ position: 'absolute', bottom: -80, right: -800 }}
149
165
  />
150
- <Heading level="1" theme="dark" align="center">
166
+ <Heading slot="heading" level="1">
151
167
  Harness AI to transform business processes
152
168
  </Heading>
153
- <Text variant="large" theme="dark" align="center">
169
+ <Text slot="description" variant="large">
154
170
  Around the world, leading enterprises use Affinda's AI agents...
155
171
  </Text>
156
- <div style={{ display: 'flex', gap: '12px', justifyContent: 'center', marginTop: '2rem' }}>
172
+ <ButtonGroup slot="buttons" direction="horizontal" gap="12px">
157
173
  <Button variant="primary">Discover the platform</Button>
158
174
  <Button variant="secondary">Explore solutions</Button>
159
- </div>
175
+ </ButtonGroup>
160
176
  </HeroSection>
161
177
  ```
162
178
 
163
179
  **Props:**
164
- - `variant`: `"light"` | `"dark"` (default: `"dark"`)
180
+ - `theme`: `"white"` | `"inkwell"` | `"mist-green"` | `"soft-clay"` (default: `"inkwell"`)
165
181
  - `withDecoration`: boolean - Shows decoration slot
166
182
  - `minHeight`: string - CSS min-height value
183
+ - `headingSize`: `1` | `2` | `3` | `4` | `5` - Controls heading size and spacing (default: `1`)
184
+ - `textAlignment`: `"left"` | `"center"` - Text alignment (default: `"center"`)
185
+ - `buttonAlignment`: `"horizontal"` | `"vertical"` - Button layout direction (default: `"horizontal"`)
186
+ - `maxWidth`: number - Maximum width for the copy section in pixels
187
+
188
+ **Slots:**
189
+ - `heading` - The main heading (typically a `<Heading>` component)
190
+ - `description` - Description text (typically a `<Text>` component)
191
+ - `buttons` - CTA buttons (typically a `<ButtonGroup>` or individual buttons)
192
+ - `decoration` - Optional decorative element (e.g., `<PaperclipDecoration>`)
167
193
 
168
194
  **Features:**
169
- - Automatically applies correct text colors for dark backgrounds
195
+ - Uses TypographyLockup internally for consistent heading/description/button layout
196
+ - Child components (Heading, Text, Button) automatically inherit theme colors - no manual theme props needed
170
197
  - Built-in padding that accounts for floating navbar
171
198
  - Responsive on mobile
172
199
 
@@ -177,7 +204,7 @@ The section component provides consistent spacing and backgrounds for page secti
177
204
  ```tsx
178
205
  import { Section, Heading, Text } from '@affinda/react';
179
206
 
180
- <Section padding="default" background="level1" container={true}>
207
+ <Section padding="default" theme="mist-green" container={true}>
181
208
  <Heading level="2" align="center">Work smarter, grow faster</Heading>
182
209
  <Text variant="large" align="center">Feature content here...</Text>
183
210
  </Section>
@@ -185,26 +212,32 @@ import { Section, Heading, Text } from '@affinda/react';
185
212
 
186
213
  **Props:**
187
214
  - `padding`: `"tight"` (48px) | `"default"` (96px) | `"loose"` (120px)
188
- - `background`: `"white"` | `"level1"` | `"dark"` | `"inkwell"`
215
+ - `theme`: `"white"` | `"inkwell"` | `"mist-green"` | `"soft-clay"` (default: `"white"`)
189
216
  - `container`: boolean - Auto-wraps content in Container
190
217
 
191
- > **Contrast helper:** When `background="dark"` or `background="inkwell"`, `Section` automatically exposes CSS variables so nested `Heading`, `Text`, and `TypographyLockup` components render in mist-green, even if you forget to set `theme="dark"`. Buttons still need `darkBackground={true}` (see below).
218
+ > **Theme inheritance:** Child components (Heading, Text, Button) automatically inherit the section's theme colors. No manual theme props needed on children!
192
219
 
193
- ### Card with Photo Background
220
+ ### Card
194
221
 
195
- Cards now support photo backgrounds with gradient overlays.
222
+ Cards support themed backgrounds and photo backgrounds. Use the `theme` prop for consistent styling with theme inheritance.
196
223
 
197
224
  ```tsx
198
225
  import { Card, Heading, Text } from '@affinda/react';
199
226
 
200
- // Light background card
201
- <Card backgroundColor="var(--colour-background-level1)">
227
+ // Themed card (recommended) - children inherit theme colors automatically
228
+ <Card theme="mist-green">
202
229
  <Heading level="3">Automate any document with 99%+ accuracy</Heading>
203
230
  <Text variant="large">Extract any information...</Text>
204
231
  <img src="screenshot.webp" alt="Feature" />
205
232
  </Card>
206
233
 
207
- // Photo background card with dark overlay
234
+ // Dark themed card
235
+ <Card theme="inkwell">
236
+ <Heading level="3">Build models in minutes</Heading>
237
+ <Text variant="large">Affinda is the only AI platform...</Text>
238
+ </Card>
239
+
240
+ // Photo background card (for custom backgrounds)
208
241
  <Card backgroundImage="photo.jpg" darkOverlay={true}>
209
242
  <Heading level="3">Build models in minutes</Heading>
210
243
  <Text variant="large">Affinda is the only AI platform...</Text>
@@ -212,9 +245,10 @@ import { Card, Heading, Text } from '@affinda/react';
212
245
  ```
213
246
 
214
247
  **Props:**
215
- - `backgroundColor`: CSS color or variable
248
+ - `theme`: `"white"` | `"inkwell"` | `"mist-green"` | `"soft-clay"` (recommended)
249
+ - `backgroundColor`: CSS color or variable (legacy, use theme instead)
216
250
  - `backgroundImage`: URL to background image
217
- - `darkOverlay`: boolean - Applies gradient overlay with white text
251
+ - `darkOverlay`: boolean - Applies gradient overlay for text readability on photos
218
252
 
219
253
  ### PaperclipDecoration
220
254
 
@@ -225,7 +259,7 @@ Decorative SVG paperclip graphic for hero sections.
225
259
  ```tsx
226
260
  import { HeroSection, PaperclipDecoration } from '@affinda/react';
227
261
 
228
- <HeroSection variant="dark" withDecoration={true}>
262
+ <HeroSection theme="inkwell" withDecoration={true}>
229
263
  <PaperclipDecoration
230
264
  slot="decoration"
231
265
  style={{
@@ -326,10 +360,10 @@ import { HeroSection, PaperclipDecoration } from '@affinda/react';
326
360
  >
327
361
  <Heading level="1">Automate Your Workflow</Heading>
328
362
  <Text slot="description">Extract data from documents in seconds</Text>
329
- <div slot="buttons">
363
+ <ButtonGroup slot="buttons" direction="horizontal">
330
364
  <Button variant="primary">Get Started</Button>
331
365
  <Button variant="secondary">Learn More</Button>
332
- </div>
366
+ </ButtonGroup>
333
367
  </TypographyLockup>
334
368
  ```
335
369
 
@@ -340,7 +374,7 @@ import { HeroSection, PaperclipDecoration } from '@affinda/react';
340
374
  - Secondary actions: Use `variant="secondary"`
341
375
  - Sizes: `small`, `default`
342
376
  - Can include icons in left or right slots
343
- - On dark backgrounds, pass `darkBackground={true}` so borders/text flip automatically
377
+ - Buttons automatically inherit theme colors from parent Section/HeroSection/Card
344
378
 
345
379
  ```tsx
346
380
  <Button variant="primary">Sign Up Now</Button>
@@ -364,11 +398,31 @@ import { HeroSection, PaperclipDecoration } from '@affinda/react';
364
398
  - Common uses: Close buttons, navigation arrows, menu toggles
365
399
 
366
400
  ```tsx
401
+ import { IconButton, Close, Menu } from '@affinda/react';
402
+
367
403
  <IconButton variant="secondary" aria-label="Close dialog">
368
- <svg>...</svg>
404
+ <Close size={24} />
405
+ </IconButton>
406
+
407
+ <IconButton variant="tertiary" size="small" aria-label="Toggle menu">
408
+ <Menu size={20} />
369
409
  </IconButton>
370
410
  ```
371
411
 
412
+ #### Tags
413
+
414
+ **Tag**
415
+ - Use for categorization, topics, filters, or metadata display
416
+ - Variants: `sand` (default - soft-clay/tan) or `light` (mist-green)
417
+ - Sizes: `x-small`, `small` (default), `large`
418
+ - Can be clickable links with `href` prop
419
+
420
+ ```tsx
421
+ <Tag>AI</Tag>
422
+ <Tag variant="light">OCR</Tag>
423
+ <Tag variant="sand" size="large" href="/topics/ml">Machine Learning</Tag>
424
+ ```
425
+
372
426
  #### Navigation
373
427
 
374
428
  **Navbar**
@@ -377,17 +431,29 @@ import { HeroSection, PaperclipDecoration } from '@affinda/react';
377
431
 
378
432
  Site-wide navigation header with responsive design and mobile menu support.
379
433
 
380
- **Required Slots:**
381
- - `logo` - Brand logo (left side)
434
+ **Layout Behavior:**
435
+
436
+ The Navbar renders two elements:
437
+ 1. A **spacer element** that sits in normal document flow and reserves vertical space
438
+ 2. A **fixed navbar** that floats above the page content
439
+
440
+ This prevents page content from being hidden behind the navbar. The spacer automatically adjusts its height at different breakpoints:
441
+ - Desktop: 100px
442
+ - Tablet (≤1024px): 88px
443
+ - Mobile (≤991px): 72px
444
+
445
+ **Props:**
446
+ - `showDefaultLogo` (boolean, default: `true`) - Whether to show the default Affinda logo when no logo slot content is provided
447
+ - `theme`: `"white"` | `"inkwell"` | `"mist-green"` | `"soft-clay"` - Sets the spacer background color to match the section below the navbar
448
+
449
+ **Slots:**
450
+ - `logo` - Brand logo (left side) - *optional*, defaults to Affinda logo
382
451
  - `start` - Primary navigation links (center-left)
383
452
  - `end` - Secondary navigation and actions (right side)
384
453
  - `button` - Call-to-action button (far right)
385
454
 
386
455
  ```tsx
387
456
  <Navbar>
388
- {/* Logo slot - required */}
389
- <Logo slot="logo" />
390
-
391
457
  {/* Start slot - main navigation items */}
392
458
  <div slot="start">
393
459
  <NavItem hierarchy="primary" variant="01" href="/platform">
@@ -418,23 +484,6 @@ Site-wide navigation header with responsive design and mobile menu support.
418
484
  </Navbar>
419
485
  ```
420
486
 
421
- **Common Mistake:**
422
- ```tsx
423
- // ❌ WRONG - Direct children are ignored
424
- <Navbar>
425
- <Logo />
426
- <NavItem href="/home">Home</NavItem>
427
- </Navbar>
428
-
429
- // ✅ CORRECT - Use slots
430
- <Navbar>
431
- <Logo slot="logo" />
432
- <div slot="start">
433
- <NavItem href="/home">Home</NavItem>
434
- </div>
435
- </Navbar>
436
- ```
437
-
438
487
  **NavItem**
439
488
  - Individual navigation links
440
489
  - Hierarchy: `primary` (main nav), `secondary` (utility nav)
@@ -448,29 +497,32 @@ Site-wide navigation header with responsive design and mobile menu support.
448
497
  - Auto-cycles through items with a visual progress timer
449
498
  - Displays accompanying images that change with each item
450
499
  - Timer resets when user clicks an item
500
+ - **Must be wrapped in a Section** which provides theme context and padding
451
501
 
452
502
  ```tsx
453
- import { FeatureAccordion } from '@affinda/react';
454
-
455
- <FeatureAccordion
456
- heading="Give AI agents your paperwork"
457
- items={JSON.stringify([
458
- {
459
- title: "Automate document processing with 99%+ accuracy",
460
- description: "Extract any information from any document with industry-leading precision.",
461
- imageUrl: "https://example.com/feature1.jpg",
462
- imageAlt: "Document automation"
463
- },
464
- {
465
- title: "Build models in minutes, not months",
466
- description: "Affinda learns instantly from every interaction.",
467
- imageUrl: "https://example.com/feature2.jpg",
468
- imageAlt: "Fast model building"
469
- }
470
- ])}
471
- cycleInterval={6000}
472
- autoCycle={true}
473
- />
503
+ import { Section, FeatureAccordion } from '@affinda/react';
504
+
505
+ <Section theme="mist-green" padding="default">
506
+ <FeatureAccordion
507
+ heading="Give AI agents your paperwork"
508
+ items={JSON.stringify([
509
+ {
510
+ title: "Automate document processing with 99%+ accuracy",
511
+ description: "Extract any information from any document with industry-leading precision.",
512
+ imageUrl: "https://example.com/feature1.jpg",
513
+ imageAlt: "Document automation"
514
+ },
515
+ {
516
+ title: "Build models in minutes, not months",
517
+ description: "Affinda learns instantly from every interaction.",
518
+ imageUrl: "https://example.com/feature2.jpg",
519
+ imageAlt: "Fast model building"
520
+ }
521
+ ])}
522
+ cycleInterval={6000}
523
+ autoCycle={true}
524
+ />
525
+ </Section>
474
526
  ```
475
527
 
476
528
  **Props:**
@@ -479,33 +531,43 @@ import { FeatureAccordion } from '@affinda/react';
479
531
  - `cycleInterval`: Auto-cycle interval in milliseconds (default: 6000)
480
532
  - `autoCycle`: Enable/disable auto-cycling (default: true)
481
533
 
482
- **CtaSection**
483
- - Call-to-action section with illustration and decorative background
484
- - Styled to match the affinda.com design
534
+ **Section Props (wrapper):**
535
+ - `theme`: `"white"` | `"inkwell"` | `"mist-green"` | `"soft-clay"` - Sets background and typography colors
536
+ - `padding`: `"tight"` | `"default"` | `"loose"` - Vertical spacing (default: `"default"`)
537
+
538
+ **InPageBanner**
539
+ - Call-to-action banner card with illustration and decorative wave background
540
+ - Place inside a neutral (white) Section to show off its themed background
541
+ - Use `getIllustrationUrlByScene()` from `@affinda/illustrations` for theme-matched illustrations
485
542
 
486
543
  ```tsx
487
- import { CtaSection } from '@affinda/react';
544
+ import { Section, InPageBanner } from '@affinda/react';
488
545
  import { getIllustrationUrlByScene } from '@affinda/illustrations';
489
546
 
490
- <CtaSection
491
- heading="See what our AI agents can do for you"
492
- description="Upload your documents and watch our AI agents get to work."
493
- primaryButtonText="Try for free"
494
- primaryButtonUrl="https://app.affinda.com/auth/register"
495
- secondaryButtonText="Talk to us"
496
- secondaryButtonUrl="/contact"
497
- illustrationUrl={getIllustrationUrlByScene('automate', 'inkwell')}
498
- />
547
+ <Section padding="default" theme="white" container={true}>
548
+ <InPageBanner
549
+ theme="mist-green"
550
+ heading="See what our AI agents can do for you"
551
+ description="Upload your documents and watch our AI agents get to work."
552
+ primaryButtonText="Try for free"
553
+ primaryButtonUrl="https://app.affinda.com/auth/register"
554
+ secondaryButtonText="Talk to us"
555
+ secondaryButtonUrl="/contact"
556
+ illustrationUrl={getIllustrationUrlByScene('automate', 'mist-green')}
557
+ />
558
+ </Section>
499
559
  ```
500
560
 
501
561
  **Props:**
502
- - `heading`: Section heading text
562
+ - `theme`: `"white-ivory"` | `"inkwell"` | `"mist-green"` | `"soft-clay"` (default: `"mist-green"`) - Sets background and typography colors
563
+ - `heading`: Banner heading text
503
564
  - `description`: Description text below heading
504
565
  - `primaryButtonText`: Text for primary CTA button
505
566
  - `primaryButtonUrl`: URL for primary button
506
- - `secondaryButtonText`: Text for secondary button
567
+ - `secondaryButtonText`: Text for secondary button (optional)
507
568
  - `secondaryButtonUrl`: URL for secondary button
508
- - `illustrationUrl`: URL to illustration image (use @affinda/illustrations)
569
+ - `illustrationUrl`: Illustration image URL. Use `getIllustrationUrlByScene(scene, theme)` from `@affinda/illustrations` for theme-matched illustrations. Available scenes: `'document-raise'`, `'thinking'`, `'shapes'`, `'team-leader'`, `'grow-business'`, `'document-type'`, `'industries'`, `'accuracy'`, `'intelligence'`, `'page-turn'`, `'automate'`
570
+ - `showWaveDecoration`: Whether to show the decorative wave overlay (default: true)
509
571
 
510
572
  #### Social Proof & Testimonials
511
573
 
@@ -522,38 +584,40 @@ import { getIllustrationUrlByScene } from '@affinda/illustrations';
522
584
  attribution="– Jane Doe, CEO, Company Name"
523
585
  readMoreLink="https://example.com/case-study"
524
586
  >
525
- <div slot="stats">
526
- <TestimonialStat value="95%" description="reduction in processing time" />
527
- <TestimonialStat value="10×" description="increase in throughput" />
528
- </div>
587
+ <TestimonialStat slot="stats" value="95%" description="reduction in processing time" />
588
+ <TestimonialStat slot="stats" value="10×" description="increase in throughput" />
529
589
  </Testimonial>
530
590
  ```
531
591
 
532
592
  **TestimonialCarousel**
593
+ - Wrap with Section for theming and Container for layout (like other components)
533
594
  - Automatically handles navigation between multiple testimonials
534
- - Includes slide animations and progress indicators
535
- - Navigation buttons positioned for optimal UX
536
- - Just wrap multiple Testimonial components
595
+ - Includes progress indicator
537
596
 
538
597
  ```tsx
539
- <TestimonialCarousel>
540
- <Testimonial {...testimonial1Props}>
541
- <div slot="stats">...</div>
542
- </Testimonial>
543
- <Testimonial {...testimonial2Props}>
544
- <div slot="stats">...</div>
545
- </Testimonial>
546
- </TestimonialCarousel>
598
+ <Section padding="default" theme="white" container>
599
+ <TestimonialCarousel>
600
+ <Testimonial {...testimonial1Props}>
601
+ <TestimonialStat slot="stats" value="95%" description="processing time reduction" />
602
+ <TestimonialStat slot="stats" value="10×" description="throughput increase" />
603
+ </Testimonial>
604
+ <Testimonial {...testimonial2Props}>
605
+ <TestimonialStat slot="stats" value="99%" description="accuracy rate" />
606
+ </Testimonial>
607
+ </TestimonialCarousel>
608
+ </Section>
547
609
  ```
548
610
 
549
611
  **TestimonialStat**
550
612
  - Display key metrics within testimonials
613
+ - Use `slot="stats"` on each stat to position correctly
551
614
  - Use 2-4 stats per testimonial for best impact
552
615
  - Optional accent border for qualitative statements
553
616
 
554
617
  ```tsx
555
- <TestimonialStat value="99%" description="accuracy rate" />
618
+ <TestimonialStat slot="stats" value="99%" description="accuracy rate" />
556
619
  <TestimonialStat
620
+ slot="stats"
557
621
  value=""
558
622
  description="Reduced manual errors significantly"
559
623
  accentBorder={true}
@@ -565,7 +629,7 @@ import { getIllustrationUrlByScene } from '@affinda/illustrations';
565
629
  **Logo**
566
630
  - Affinda logo component with consistent sizing
567
631
  - Use in Navbar and footer
568
- - Automatically handles light/dark variants
632
+ - Renders as inline SVG for crisp display at any size
569
633
 
570
634
  ```tsx
571
635
  <Logo />
@@ -645,10 +709,8 @@ function Hero() {
645
709
  <p slot="description">
646
710
  Extract data from documents with AI-powered accuracy
647
711
  </p>
648
- <div slot="buttons">
649
- <Button variant="primary">Get Started</Button>
650
- <Button variant="secondary">Learn More</Button>
651
- </div>
712
+ <Button slot="buttons" variant="primary">Get Started</Button>
713
+ <Button slot="buttons" variant="secondary">Learn More</Button>
652
714
  </TypographyLockup>
653
715
  );
654
716
  }
@@ -657,12 +719,12 @@ function Hero() {
657
719
  ### Navigation
658
720
 
659
721
  ```tsx
660
- import { Navbar, NavItem, Logo, Button } from '@affinda/react';
722
+ import { Navbar, NavItem, Button } from '@affinda/react';
661
723
 
662
724
  function Header() {
663
725
  return (
726
+ // Navbar displays the default Affinda logo automatically
664
727
  <Navbar>
665
- <Logo slot="logo" />
666
728
  <div slot="start">
667
729
  <NavItem hierarchy="primary" variant="01" href="/">
668
730
  Home
@@ -736,10 +798,274 @@ See the [@affinda/tokens documentation](https://www.npmjs.com/package/@affinda/t
736
798
 
737
799
  Full TypeScript type definitions are included for all components and props.
738
800
 
801
+ ## Custom Styling
802
+
803
+ All components accept a `style` prop for applying inline CSS styles directly to the component's root element:
804
+
805
+ ```tsx
806
+ import { Button, Section, Heading } from '@affinda/react';
807
+
808
+ // Apply custom styles to any component
809
+ <Button variant="primary" style={{ marginTop: '20px', opacity: 0.9 }}>
810
+ Custom Styled Button
811
+ </Button>
812
+
813
+ <Section theme="white" style={{ borderRadius: '16px', boxShadow: '0 4px 12px rgba(0,0,0,0.1)' }}>
814
+ <Heading level="2">Styled Section</Heading>
815
+ </Section>
816
+ ```
817
+
818
+ The `style` prop is passed through to the web component's host element, allowing you to override or extend component styles as needed.
819
+
820
+ ## Common UI Patterns
821
+
822
+ Use these component combinations for common marketing page patterns. **Always check this section before writing custom CSS or HTML.**
823
+
824
+ ### Grid of Feature Items with Icons
825
+
826
+ ```tsx
827
+ import { Section, FeatureGrid, IconText } from '@affinda/react';
828
+
829
+ <Section theme="mist-green" container={true}>
830
+ <FeatureGrid columns={4} mobileLayout="list">
831
+ <IconText icon="time" headingSize={4}>
832
+ Fast Processing
833
+ <span slot="description">Process documents in seconds.</span>
834
+ </IconText>
835
+ <IconText icon="verification-01" headingSize={4}>
836
+ High Accuracy
837
+ <span slot="description">99%+ extraction accuracy.</span>
838
+ </IconText>
839
+ <IconText icon="security-01" headingSize={4}>
840
+ Secure & Compliant
841
+ <span slot="description">Enterprise-grade security.</span>
842
+ </IconText>
843
+ <IconText icon="code" headingSize={4}>
844
+ Easy Integration
845
+ <span slot="description">Works with your existing systems.</span>
846
+ </IconText>
847
+ </FeatureGrid>
848
+ </Section>
849
+ ```
850
+
851
+ ### Grid of Feature Cards with Images
852
+
853
+ ```tsx
854
+ import { FeatureGrid, FeatureCard } from '@affinda/react';
855
+
856
+ <FeatureGrid columns={3} mobileLayout="scroll">
857
+ <FeatureCard theme="mist-green" cardSize="flexible" imageSrc="/feature1.jpg">
858
+ Extract Any Document
859
+ <span slot="body">AI-powered extraction for all document types.</span>
860
+ </FeatureCard>
861
+ <FeatureCard theme="soft-clay" cardSize="flexible" imageSrc="/feature2.jpg">
862
+ Validate Automatically
863
+ <span slot="body">Built-in validation catches errors.</span>
864
+ </FeatureCard>
865
+ </FeatureGrid>
866
+ ```
867
+
868
+ ### Grouped Buttons
869
+
870
+ ```tsx
871
+ import { ButtonGroup, Button } from '@affinda/react';
872
+
873
+ <ButtonGroup direction="horizontal" gap="16px">
874
+ <Button variant="primary">Get Started</Button>
875
+ <Button variant="secondary">Learn More</Button>
876
+ </ButtonGroup>
877
+ ```
878
+
879
+ ### Feature Section with Image + Grid of Items
880
+
881
+ ```tsx
882
+ import { Section, GridCallout, IconText, Button } from '@affinda/react';
883
+
884
+ <Section theme="white" container={true}>
885
+ <GridCallout imageSrc="/team.jpg" imagePosition="left" columns={2}>
886
+ Why Choose Affinda
887
+ <span slot="description">Industry-leading AI for document processing.</span>
888
+
889
+ <IconText slot="items" icon="sparkle" headingSize={4}>
890
+ AI-Powered
891
+ <span slot="description">State-of-the-art machine learning.</span>
892
+ </IconText>
893
+ <IconText slot="items" icon="security-01" headingSize={4}>
894
+ Enterprise Security
895
+ <span slot="description">SOC 2 Type II certified.</span>
896
+ </IconText>
897
+
898
+ <Button slot="cta" variant="primary">Learn More</Button>
899
+ </GridCallout>
900
+ </Section>
901
+ ```
902
+
903
+ ### Icons in Feature Lists
904
+
905
+ ```tsx
906
+ import { IconBox, IconText } from '@affinda/react';
907
+
908
+ // Standalone icons
909
+ <IconBox icon="verification-01" size="default" />
910
+
911
+ // Icon + text combinations
912
+ <IconText icon="time" headingSize={4}>
913
+ Fast Processing
914
+ <span slot="description">Documents processed in seconds.</span>
915
+ </IconText>
916
+ ```
917
+
918
+ ### Hero with Heading, Description, and Buttons
919
+
920
+ ```tsx
921
+ import { HeroSection, Heading, Text, ButtonGroup, Button } from '@affinda/react';
922
+
923
+ <HeroSection theme="inkwell" minHeight="80vh" headingSize={1} textAlignment="center">
924
+ <Heading slot="heading" level="1">Document Automation</Heading>
925
+ <Text slot="description" variant="large">
926
+ Extract data from any document with AI.
927
+ </Text>
928
+ <ButtonGroup slot="buttons" direction="horizontal" gap="16px">
929
+ <Button variant="primary">Start Free Trial</Button>
930
+ <Button variant="secondary">Watch Demo</Button>
931
+ </ButtonGroup>
932
+ </HeroSection>
933
+ ```
934
+
935
+ ---
936
+
739
937
  ## For AI Agents
740
938
 
741
939
  When generating Affinda UI code:
742
940
 
941
+ ### Component Selection (Critical!)
942
+
943
+ **Always use existing components instead of custom CSS/HTML.** Before writing any layout code, check if a component exists for your use case.
944
+
945
+ | If you need... | Use this component |
946
+ |----------------|-------------------|
947
+ | Grid of items | `FeatureGrid` |
948
+ | Card with icon + text | `IconText` |
949
+ | Standalone icon | `IconBox` |
950
+ | Card with photo/screenshot | `FeatureCard` |
951
+ | Card with @affinda/illustrations | `IllustratedCard` |
952
+ | Button group | `ButtonGroup` |
953
+ | Heading + description + buttons | `TypographyLockup` |
954
+ | Section with image + feature grid | `GridCallout` |
955
+ | Two-column layout | `SplitSection` |
956
+ | Responsive grid container | `FeatureGrid` with `mobileLayout` prop |
957
+
958
+ ### Available Icons
959
+
960
+ Use icons from `@affinda/icons` with `IconBox` or `IconText`. Never use emoji.
961
+
962
+ **Common icons:**
963
+ - `time` - speed/performance
964
+ - `verification-01` - accuracy/checking
965
+ - `security-01`, `security-02` - security/compliance
966
+ - `sparkle` - AI/magic
967
+ - `productivity` - efficiency
968
+ - `code` - integration/API
969
+ - `document-upload` - documents
970
+ - `lending-01`, `lending-02` - lending industry
971
+ - `check-circle` - success/checkmarks
972
+ - `data` - data/analytics
973
+ - `gear` - settings/configuration
974
+
975
+ ```tsx
976
+ // Use with IconBox
977
+ <IconBox icon="verification-01" size="default" />
978
+
979
+ // Use with IconText
980
+ <IconText icon="sparkle" headingSize={4}>
981
+ AI-Powered Processing
982
+ <span slot="description">State-of-the-art machine learning.</span>
983
+ </IconText>
984
+ ```
985
+
986
+ ### Theme System (Important!)
987
+
988
+ Use the 4-value theme system on container components. Child components inherit colors automatically:
989
+
990
+ ```tsx
991
+ <Section theme="inkwell">
992
+ <Heading level="2">Title</Heading> {/* Automatically light text */}
993
+ <Text>Content</Text> {/* Automatically light text */}
994
+ <Button variant="primary">Action</Button> {/* Automatically themed */}
995
+ </Section>
996
+ ```
997
+
998
+ **Available themes:** `"white"` | `"inkwell"` | `"mist-green"` | `"soft-clay"`
999
+
1000
+ ### Self-Theming Components (No Section Wrapper!)
1001
+
1002
+ Some components provide their own themed backgrounds. **Do NOT wrap these in a Section** — they handle their own background color and spacing.
1003
+
1004
+ | Component | Provides Own Background | Correct Usage |
1005
+ |-----------|------------------------|---------------|
1006
+ | `HeroSection` | Yes | Use directly, set `theme` prop |
1007
+ | `ClientCarousel` | Yes | Use directly, set `theme` prop to match adjacent section |
1008
+ | `InPageBanner` | Yes | Wrap in neutral `Section theme="white"` to show contrast |
1009
+
1010
+ ```tsx
1011
+ <ClientCarousel theme="inkwell">...</ClientCarousel>
1012
+ ```
1013
+
1014
+ ### ClientCarousel Theme Matching
1015
+
1016
+ When using `ClientCarousel`, set its `theme` prop to match the section **above** it for visual continuity. This creates a seamless transition between sections.
1017
+
1018
+ ```tsx
1019
+ <HeroSection theme="inkwell">
1020
+ {/* Hero content */}
1021
+ </HeroSection>
1022
+ <ClientCarousel theme="inkwell">
1023
+ {/* Logo wells - theme matches preceding HeroSection */}
1024
+ </ClientCarousel>
1025
+ ```
1026
+
1027
+ ### FeatureAccordion (Wrap in Section!)
1028
+
1029
+ Unlike self-theming components, `FeatureAccordion` should be wrapped in a `Section` which provides the theme context, padding, and container.
1030
+
1031
+ ```tsx
1032
+ <Section theme="soft-clay" padding="default">
1033
+ <FeatureAccordion
1034
+ heading="Give AI agents your paperwork"
1035
+ items={JSON.stringify([...])}
1036
+ />
1037
+ </Section>
1038
+ ```
1039
+
1040
+ ### Slot-Based Components
1041
+
1042
+ Several components require `slot` attributes on children:
1043
+
1044
+ ```tsx
1045
+ // Navbar slots: logo, start, end, button
1046
+ <Navbar>
1047
+ <div slot="start"><NavItem href="/">Home</NavItem></div>
1048
+ <Button slot="button">CTA</Button>
1049
+ </Navbar>
1050
+
1051
+ // Footer slots: logo, social, contact, nav, legal, badges
1052
+ // ClientCarousel slots: row-1, row-2
1053
+ // Button slots: icon-left, icon-right
1054
+ // TypographyLockup slots: description, buttons
1055
+ ```
1056
+
1057
+ ### FeatureAccordion Items
1058
+
1059
+ The `items` prop requires JSON.stringify():
1060
+
1061
+ ```tsx
1062
+ <Section theme="mist-green" padding="default">
1063
+ <FeatureAccordion items={JSON.stringify([{ title: "...", description: "..." }])} />
1064
+ </Section>
1065
+ ```
1066
+
1067
+ ### Brand Colors
1068
+
743
1069
  1. **Always use Affinda brand colors:**
744
1070
  - Primary: Mist Green (`#C6D5D1`)
745
1071
  - Text: Inkwell (`#14343B`)