lucent-ui 0.33.0 → 0.35.0

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.
@@ -6,6 +6,10 @@ import { PATTERN as FormLayout } from '../src/manifest/patterns/form-layout.patt
6
6
  import { PATTERN as EmptyStateCard } from '../src/manifest/patterns/empty-state-card.pattern.js';
7
7
  import { PATTERN as CollapsibleCard } from '../src/manifest/patterns/collapsible-card.pattern.js';
8
8
  import { PATTERN as SearchFilterBar } from '../src/manifest/patterns/search-filter-bar.pattern.js';
9
+ import { PATTERN as ProductItemCard } from '../src/manifest/patterns/product-item-card.pattern.js';
10
+ import { PATTERN as NotificationCard } from '../src/manifest/patterns/notification-card.pattern.js';
11
+ import { PATTERN as ConfirmationDialog } from '../src/manifest/patterns/confirmation-dialog.pattern.js';
12
+ import { PATTERN as BulkActionBar } from '../src/manifest/patterns/bulk-action-bar.pattern.js';
9
13
  export const ALL_PATTERNS = [
10
14
  ProfileCard,
11
15
  SettingsPanel,
@@ -15,4 +19,8 @@ export const ALL_PATTERNS = [
15
19
  EmptyStateCard,
16
20
  CollapsibleCard,
17
21
  SearchFilterBar,
22
+ ProductItemCard,
23
+ NotificationCard,
24
+ ConfirmationDialog,
25
+ BulkActionBar,
18
26
  ];
@@ -39,6 +39,20 @@ export const COMPONENT_MANIFEST = {
39
39
  description: '"code" renders a <pre><code> block with horizontal scroll. ' +
40
40
  '"prompt" renders a single-line truncated span suited to AI prompts.',
41
41
  },
42
+ {
43
+ name: 'minimal',
44
+ type: 'boolean',
45
+ required: false,
46
+ default: 'false',
47
+ description: 'Hides the header bar and shows only a corner copy button overlay.',
48
+ },
49
+ {
50
+ name: 'wrap',
51
+ type: 'boolean',
52
+ required: false,
53
+ default: 'false',
54
+ description: 'When true, wraps long lines instead of scrolling horizontally.',
55
+ },
42
56
  {
43
57
  name: 'helperText',
44
58
  type: 'string',
@@ -0,0 +1,71 @@
1
+ export const PATTERN = {
2
+ id: 'bulk-action-bar',
3
+ name: 'Bulk Action Bar',
4
+ description: 'Sticky bar that appears when table rows are selected. Shows selection count, bulk action buttons, and a clear selection control.',
5
+ category: 'action',
6
+ components: ['checkbox', 'text', 'button', 'button-group', 'divider', 'row'],
7
+ structure: `
8
+ Row gap="3" align="center" (surface background, padding=md)
9
+ ├── Checkbox (indeterminate when partial)
10
+ ├── Text (sm, semibold) ← "3 selected"
11
+ ├── Divider (vertical)
12
+ ├── ButtonGroup
13
+ │ ├── Button (outline, sm) ← "Export"
14
+ │ ├── Button (outline, sm) ← "Archive"
15
+ │ └── Button (danger-outline, sm) ← "Delete"
16
+ └── Row flex=1 justify="end"
17
+ └── Button (ghost, sm) ← "Clear selection"
18
+ `.trim(),
19
+ code: `<Row gap="3" align="center" style={{ padding: 'var(--lucent-space-3) var(--lucent-space-4)', background: 'var(--lucent-surface)', borderRadius: 'var(--lucent-radius-lg)', border: '1px solid var(--lucent-border-default)' }}>
20
+ <Checkbox indeterminate checked onChange={() => {}} />
21
+ <Text size="sm" weight="semibold">3 selected</Text>
22
+ <Divider orientation="vertical" />
23
+ <ButtonGroup>
24
+ <Button variant="outline" size="sm">Export</Button>
25
+ <Button variant="outline" size="sm">Archive</Button>
26
+ <Button variant="danger-outline" size="sm">Delete</Button>
27
+ </ButtonGroup>
28
+ <Row style={{ flex: 1, justifyContent: 'flex-end' }}>
29
+ <Button variant="ghost" size="sm">Clear selection</Button>
30
+ </Row>
31
+ </Row>`,
32
+ variants: [
33
+ {
34
+ title: 'Minimal (single action)',
35
+ code: `<Row gap="3" align="center" style={{ padding: 'var(--lucent-space-3) var(--lucent-space-4)', background: 'var(--lucent-surface)', borderRadius: 'var(--lucent-radius-lg)', border: '1px solid var(--lucent-border-default)' }}>
36
+ <Checkbox checked onChange={() => {}} />
37
+ <Text size="sm" weight="semibold">12 selected</Text>
38
+ <Row style={{ flex: 1, justifyContent: 'flex-end' }}>
39
+ <Button variant="danger" size="sm">Delete selected</Button>
40
+ </Row>
41
+ </Row>`,
42
+ },
43
+ {
44
+ title: 'With count badge and secondary actions',
45
+ code: `<Row gap="3" align="center" style={{ padding: 'var(--lucent-space-3) var(--lucent-space-4)', background: 'var(--lucent-surface)', borderRadius: 'var(--lucent-radius-lg)', border: '1px solid var(--lucent-border-default)' }}>
46
+ <Checkbox indeterminate checked onChange={() => {}} />
47
+ <Row gap="2" align="center">
48
+ <Text size="sm" weight="semibold">5 of 24 selected</Text>
49
+ <Button variant="ghost" size="xs">Select all</Button>
50
+ </Row>
51
+ <Divider orientation="vertical" />
52
+ <Button variant="outline" size="sm">Assign label</Button>
53
+ <Button variant="outline" size="sm">Move to</Button>
54
+ <Button variant="danger-outline" size="sm">Delete</Button>
55
+ <Row style={{ flex: 1, justifyContent: 'flex-end' }}>
56
+ <Button variant="ghost" size="sm">Clear</Button>
57
+ </Row>
58
+ </Row>`,
59
+ },
60
+ ],
61
+ designNotes: 'The bar uses a Row with center alignment so all elements sit on the same ' +
62
+ 'horizontal baseline. The Checkbox reflects selection state — indeterminate ' +
63
+ 'when some rows are selected, checked when all are. A vertical Divider ' +
64
+ 'visually separates the selection count from the action buttons. ButtonGroup ' +
65
+ 'clusters related actions with shared border radius. The danger-outline ' +
66
+ 'variant on the Delete button signals destructive intent without the visual ' +
67
+ 'weight of a filled danger button. The clear selection Button is pushed to ' +
68
+ 'the far right via flex: 1 on its wrapper Row, keeping it accessible but ' +
69
+ 'visually subordinate. The minimal variant drops the ButtonGroup and Divider ' +
70
+ 'for a simpler single-action layout.',
71
+ };
@@ -0,0 +1,95 @@
1
+ export const PATTERN = {
2
+ id: 'confirmation-dialog',
3
+ name: 'Confirmation Dialog',
4
+ description: 'Centered modal-style card for destructive action confirmations with danger button pairing. For delete/remove/reset flows.',
5
+ category: 'action',
6
+ components: ['card', 'icon', 'text', 'button', 'input', 'stack', 'row'],
7
+ structure: `
8
+ Card (elevated, padding="lg", maxWidth=400)
9
+ └── Stack gap="8" align="center"
10
+ ├── Icon (lg, danger color) ← warning icon
11
+ ├── Stack gap="1" align="center"
12
+ │ ├── Text (lg, semibold, center) ← "Delete project?"
13
+ │ └── Text (sm, secondary, center) ← consequence description
14
+ └── Row gap="3"
15
+ ├── Button (outline, full width) ← "Cancel"
16
+ └── Button (danger, full width) ← "Delete"
17
+ `.trim(),
18
+ code: `<Card variant="elevated" padding="lg" style={{ maxWidth: 400 }}>
19
+ <Stack gap="8" align="center">
20
+ <Icon size="xl" color="var(--lucent-danger-text)">
21
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={1.5} strokeLinecap="round" strokeLinejoin="round">
22
+ <path d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z" />
23
+ <line x1={12} y1={9} x2={12} y2={13} />
24
+ <line x1={12} y1={17} x2={12.01} y2={17} />
25
+ </svg>
26
+ </Icon>
27
+ <Stack gap="1" align="center">
28
+ <Text size="lg" weight="semibold">Delete project?</Text>
29
+ <Text size="sm" color="secondary" align="center">This will permanently delete "Acme Corp" and all of its data. This action cannot be undone.</Text>
30
+ </Stack>
31
+ <Row gap="3" style={{ width: '100%' }}>
32
+ <Button variant="outline" style={{ flex: 1 }}>Cancel</Button>
33
+ <Button variant="danger" style={{ flex: 1 }}>Delete</Button>
34
+ </Row>
35
+ </Stack>
36
+ </Card>`,
37
+ variants: [
38
+ {
39
+ title: 'With typed confirmation',
40
+ code: `<Card variant="elevated" padding="lg" style={{ maxWidth: 400 }}>
41
+ <Stack gap="8" align="center">
42
+ <Icon size="xl" color="var(--lucent-danger-text)">
43
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={1.5} strokeLinecap="round" strokeLinejoin="round">
44
+ <path d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z" />
45
+ <line x1={12} y1={9} x2={12} y2={13} />
46
+ <line x1={12} y1={17} x2={12.01} y2={17} />
47
+ </svg>
48
+ </Icon>
49
+ <Stack gap="1" align="center">
50
+ <Text size="lg" weight="semibold">Delete your account?</Text>
51
+ <Text size="sm" color="secondary" align="center">All projects, data, and billing history will be permanently removed. Type DELETE to confirm.</Text>
52
+ </Stack>
53
+ <Input placeholder="Type DELETE to confirm" size="md" style={{ width: '100%' }} />
54
+ <Row gap="3" style={{ width: '100%' }}>
55
+ <Button variant="outline" style={{ flex: 1 }}>Cancel</Button>
56
+ <Button variant="danger" style={{ flex: 1 }} disabled>Delete account</Button>
57
+ </Row>
58
+ </Stack>
59
+ </Card>`,
60
+ },
61
+ {
62
+ title: 'Non-destructive confirmation',
63
+ code: `<Card variant="elevated" padding="lg" style={{ maxWidth: 400 }}>
64
+ <Stack gap="8" align="center">
65
+ <Icon size="xl" color="var(--lucent-info-text)">
66
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={1.5} strokeLinecap="round" strokeLinejoin="round">
67
+ <circle cx={12} cy={12} r={10} />
68
+ <line x1={12} y1={16} x2={12} y2={12} />
69
+ <line x1={12} y1={8} x2={12.01} y2={8} />
70
+ </svg>
71
+ </Icon>
72
+ <Stack gap="1" align="center">
73
+ <Text size="lg" weight="semibold">Publish changes?</Text>
74
+ <Text size="sm" color="secondary" align="center">This will make your draft visible to all team members. You can unpublish later from settings.</Text>
75
+ </Stack>
76
+ <Row gap="3" style={{ width: '100%' }}>
77
+ <Button variant="outline" style={{ flex: 1 }}>Keep as draft</Button>
78
+ <Button variant="primary" style={{ flex: 1 }}>Publish</Button>
79
+ </Row>
80
+ </Stack>
81
+ </Card>`,
82
+ },
83
+ ],
84
+ designNotes: 'The centered layout with align="center" creates a focused, modal-like feel ' +
85
+ 'even though this is a Card, not a true modal. The warning Icon at the top ' +
86
+ 'provides an immediate visual signal of severity. The text stack uses gap="1" ' +
87
+ 'to tightly couple the title and consequence description. Buttons use flex: 1 ' +
88
+ 'inside a full-width Row so they split evenly — Cancel (outline) on the left, ' +
89
+ 'destructive action (danger) on the right, following the convention of placing ' +
90
+ 'the primary action on the right. The typed confirmation variant adds an Input ' +
91
+ 'between the text and buttons with the danger Button disabled until the user ' +
92
+ 'types the confirmation text. The non-destructive variant swaps the danger ' +
93
+ 'Button for primary and the warning Icon for info, reusing the same centered ' +
94
+ 'layout for any "are you sure?" flow.',
95
+ };
@@ -0,0 +1,108 @@
1
+ export const PATTERN = {
2
+ id: 'announcement-card',
3
+ name: 'Announcement Card',
4
+ description: 'Rich announcement card with optional media slot, status icon, title, message, and action buttons. For in-page announcements, feature launches, promotions, or system notices.',
5
+ category: 'card',
6
+ components: ['card', 'icon', 'text', 'button', 'chip', 'stack', 'row'],
7
+ structure: `
8
+ Card (elevated, padding="lg", media=<img>)
9
+ └── Stack gap="4"
10
+ ├── Row gap="2" wrap ← optional badge row
11
+ │ └── Chip (accent/success, sm) ← category / "New"
12
+ ├── Stack gap="1"
13
+ │ ├── Text (md, semibold) ← title
14
+ │ └── Text (sm, secondary) ← message body
15
+ └── Row gap="2"
16
+ ├── Button (primary, sm) ← action
17
+ └── Button (ghost, sm) ← dismiss
18
+ `.trim(),
19
+ code: `<Card
20
+ variant="elevated"
21
+ padding="lg"
22
+ style={{ width: 380 }}
23
+ media={<img src="/announcements/feature-launch.jpg" alt="New dashboard" style={{ width: '100%', height: 160, objectFit: 'cover', display: 'block' }} />}
24
+ >
25
+ <Stack gap="4">
26
+ <Row gap="2">
27
+ <Chip variant="accent" size="sm">New Feature</Chip>
28
+ </Row>
29
+ <Stack gap="1">
30
+ <Text size="md" weight="semibold">Redesigned Analytics Dashboard</Text>
31
+ <Text size="sm" color="secondary">Track key metrics at a glance with our new real-time dashboard. Includes custom date ranges, export to CSV, and team sharing.</Text>
32
+ </Stack>
33
+ <Row gap="2">
34
+ <Button variant="primary" size="sm">Try it now</Button>
35
+ <Button variant="ghost" size="sm">Learn more</Button>
36
+ </Row>
37
+ </Stack>
38
+ </Card>`,
39
+ variants: [
40
+ {
41
+ title: 'System notice (no media, with status icon)',
42
+ code: `<Card variant="outline" padding="md" style={{ width: 400 }}>
43
+ <Row gap="3" align="start">
44
+ <Icon size="lg" color="var(--lucent-warning-text)">
45
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={1.5} strokeLinecap="round" strokeLinejoin="round">
46
+ <path d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z" />
47
+ <line x1={12} y1={9} x2={12} y2={13} />
48
+ <line x1={12} y1={17} x2={12.01} y2={17} />
49
+ </svg>
50
+ </Icon>
51
+ <Stack gap="2" style={{ flex: 1 }}>
52
+ <Text size="sm" weight="semibold">Storage almost full</Text>
53
+ <Text size="sm" color="secondary">You've used 92% of your storage. Upgrade your plan or delete unused files to free up space.</Text>
54
+ <Row gap="2">
55
+ <Button variant="primary" size="sm">Upgrade plan</Button>
56
+ <Button variant="ghost" size="sm">Manage storage</Button>
57
+ </Row>
58
+ </Stack>
59
+ </Row>
60
+ </Card>`,
61
+ },
62
+ {
63
+ title: 'Promotional banner with media',
64
+ code: `<Card variant="filled" padding="md" hoverable style={{ width: 380 }}>
65
+ <Row gap="5" align="center">
66
+ <div style={{ width: 80, height: 80, borderRadius: 'var(--lucent-radius-lg)', overflow: 'hidden', flexShrink: 0 }}>
67
+ <img src="/promo/spring-sale.jpg" alt="Spring sale" style={{ width: '100%', height: '100%', objectFit: 'cover', display: 'block' }} />
68
+ </div>
69
+ <Stack gap="2" style={{ flex: 1 }}>
70
+ <Row gap="2" align="center">
71
+ <Text size="md" weight="semibold">Spring Sale</Text>
72
+ <Chip variant="success" size="sm">-30%</Chip>
73
+ </Row>
74
+ <Text size="sm" color="secondary">All Pro plans are 30% off through April. Upgrade now and lock in the price for a year.</Text>
75
+ <Button variant="primary" size="sm" style={{ alignSelf: 'flex-start' }}>Claim offer</Button>
76
+ </Stack>
77
+ </Row>
78
+ </Card>`,
79
+ },
80
+ {
81
+ title: 'Success confirmation',
82
+ code: `<Card variant="outline" padding="md" style={{ width: 400, borderColor: 'var(--lucent-success-default)' }}>
83
+ <Row gap="3" align="start">
84
+ <Icon size="lg" color="var(--lucent-success-text)">
85
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={1.5} strokeLinecap="round" strokeLinejoin="round">
86
+ <path d="M22 11.08V12a10 10 0 11-5.93-9.14" />
87
+ <polyline points="22 4 12 14.01 9 11.01" />
88
+ </svg>
89
+ </Icon>
90
+ <Stack gap="1" style={{ flex: 1 }}>
91
+ <Text size="sm" weight="semibold">Payment received</Text>
92
+ <Text size="sm" color="secondary">Your invoice #1042 for $2,400.00 has been paid successfully.</Text>
93
+ </Stack>
94
+ <Button variant="ghost" size="sm">Dismiss</Button>
95
+ </Row>
96
+ </Card>`,
97
+ },
98
+ ],
99
+ designNotes: 'The default announcement card uses the Card media slot for a full-bleed hero ' +
100
+ 'image that grabs attention, followed by an optional Chip badge for categorization, ' +
101
+ 'then title + description + action buttons. This distinguishes it from the Alert ' +
102
+ 'molecule which is a lightweight status banner — the Announcement Card is richer, ' +
103
+ 'supports media, and drives the user toward an action. The system notice variant ' +
104
+ 'drops the media for a compact icon-led layout similar to Alert but with action ' +
105
+ 'buttons. The promotional variant uses an inline thumbnail (Row with rounded image) ' +
106
+ 'for a side-by-side layout that works well for offers and upsells. The success ' +
107
+ 'variant uses a tinted border to reinforce status at a glance.',
108
+ };
@@ -0,0 +1,110 @@
1
+ export const PATTERN = {
2
+ id: 'product-item-card',
3
+ name: 'Product/Item Card',
4
+ description: 'Versatile content card with media slot, title, tags, metadata, and CTA. Reusable for products, articles, team members, or any entity list.',
5
+ category: 'card',
6
+ components: ['card', 'avatar', 'icon', 'text', 'chip', 'button', 'stack', 'row'],
7
+ structure: `
8
+ Card (elevated, padding="lg", media=<img>)
9
+ └── Stack gap="4"
10
+ ├── Stack gap="1"
11
+ │ ├── Text (md, semibold) ← title
12
+ │ └── Text (sm, secondary) ← subtitle
13
+ ├── Row gap="2" wrap
14
+ │ └── Chip[] (neutral, sm) ← tags / categories
15
+ ├── Row gap="4" justify="between" align="baseline"
16
+ │ ├── Text (lg, bold, display) ← price / key metric
17
+ │ └── Text (xs, secondary) ← secondary info
18
+ └── Button (primary, full width) ← CTA
19
+ `.trim(),
20
+ code: `<Card
21
+ variant="elevated"
22
+ padding="lg"
23
+ style={{ width: 320 }}
24
+ media={<img src="/products/headphones.jpg" alt="Wireless Headphones" style={{ width: '100%', height: 180, objectFit: 'cover', display: 'block' }} />}
25
+ >
26
+ <Stack gap="4">
27
+ <Stack gap="1">
28
+ <Text size="md" weight="semibold">Wireless Headphones</Text>
29
+ <Text size="sm" color="secondary">Active noise cancelling, 40hr battery</Text>
30
+ </Stack>
31
+ <Row gap="2" wrap>
32
+ <Chip variant="neutral" size="sm">Audio</Chip>
33
+ <Chip variant="neutral" size="sm">Bluetooth</Chip>
34
+ <Chip variant="neutral" size="sm">ANC</Chip>
35
+ </Row>
36
+ <Row gap="4" justify="between" align="baseline">
37
+ <Text size="lg" weight="bold" family="display">$249.00</Text>
38
+ <Text size="xs" color="secondary">Free shipping</Text>
39
+ </Row>
40
+ <Button variant="primary" style={{ width: '100%' }}>Add to Cart</Button>
41
+ </Stack>
42
+ </Card>`,
43
+ variants: [
44
+ {
45
+ title: 'Article card',
46
+ code: `<Card variant="outline" padding="lg" hoverable style={{ width: 340 }}>
47
+ <Stack gap="4">
48
+ <Row gap="3" align="start">
49
+ <Icon size={20} color="var(--lucent-text-secondary)">
50
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={1.5} strokeLinecap="round" strokeLinejoin="round">
51
+ <path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z" />
52
+ <polyline points="14 2 14 8 20 8" />
53
+ <line x1={16} y1={13} x2={8} y2={13} />
54
+ <line x1={16} y1={17} x2={8} y2={17} />
55
+ </svg>
56
+ </Icon>
57
+ <Stack gap="1" style={{ flex: 1 }}>
58
+ <Text size="md" weight="semibold">Design Tokens at Scale</Text>
59
+ <Text size="xs" color="secondary">Published Mar 15, 2026</Text>
60
+ </Stack>
61
+ </Row>
62
+ <Text size="sm" color="secondary">
63
+ How we unified spacing, color, and typography across 12 product surfaces using a single token system.
64
+ </Text>
65
+ <Row gap="2" wrap>
66
+ <Chip variant="neutral" size="sm">Design Systems</Chip>
67
+ <Chip variant="neutral" size="sm">Tokens</Chip>
68
+ </Row>
69
+ <Row gap="4" justify="between" align="center">
70
+ <Text size="xs" color="secondary">8 min read</Text>
71
+ <Button variant="ghost" size="sm">Read more</Button>
72
+ </Row>
73
+ </Stack>
74
+ </Card>`,
75
+ },
76
+ {
77
+ title: 'Team member card',
78
+ code: `<Card variant="filled" padding="lg" style={{ width: 280 }}>
79
+ <Stack gap="4">
80
+ <Stack gap="3" align="center">
81
+ <Avatar src="/avatars/alex.jpg" alt="Alex Chen" size="lg" />
82
+ <Stack gap="0" align="center">
83
+ <Text size="md" weight="semibold">Alex Chen</Text>
84
+ <Text size="sm" color="secondary">Engineering Lead</Text>
85
+ </Stack>
86
+ </Stack>
87
+ <Row gap="2" wrap justify="center">
88
+ <Chip variant="neutral" size="sm">React</Chip>
89
+ <Chip variant="neutral" size="sm">Go</Chip>
90
+ <Chip variant="neutral" size="sm">Platform</Chip>
91
+ </Row>
92
+ <Row gap="3">
93
+ <Button variant="outline" style={{ flex: 1 }} size="sm">Profile</Button>
94
+ <Button variant="primary" style={{ flex: 1 }} size="sm">Message</Button>
95
+ </Row>
96
+ </Stack>
97
+ </Card>`,
98
+ },
99
+ ],
100
+ designNotes: 'The default product card uses the Card media slot for a full-bleed hero image ' +
101
+ 'at the top, keeping the content area clean with just title, tags, price, and CTA. ' +
102
+ 'Tags use neutral Chips at sm size for low visual weight — they inform without ' +
103
+ 'competing with the title. The price/metric row uses justify="between" with ' +
104
+ 'align="baseline" to anchor the large display-font value and the secondary caption ' +
105
+ 'to the same text baseline. A full-width primary Button as the sole CTA creates a ' +
106
+ 'clear action target. The article variant swaps the media slot for an inline Icon + ' +
107
+ 'text header and replaces the price row with read-time + ghost button, keeping the ' +
108
+ 'same vertical rhythm. The team member variant centers the content for a profile-style ' +
109
+ 'layout and uses a dual-button footer with flex: 1 for equal width.',
110
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lucent-ui",
3
- "version": "0.33.0",
3
+ "version": "0.35.0",
4
4
  "description": "An AI-first React component library with machine-readable manifests.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",