@pcoi/components 0.1.2 → 1.0.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.
Files changed (122) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +52 -0
  3. package/dist/index.d.ts +829 -609
  4. package/dist/index.js +3517 -2
  5. package/dist/styles.css +2 -0
  6. package/package.json +35 -31
  7. package/dist/components.css +0 -1
  8. package/dist/index.mjs +0 -994
  9. package/src/Badge/Badge.css +0 -40
  10. package/src/Badge/Badge.tsx +0 -36
  11. package/src/Badge/index.ts +0 -2
  12. package/src/Button/Button.css +0 -93
  13. package/src/Button/Button.figma.tsx +0 -27
  14. package/src/Button/Button.test.tsx +0 -32
  15. package/src/Button/Button.tsx +0 -47
  16. package/src/Button/index.ts +0 -1
  17. package/src/Callout/Callout.css +0 -48
  18. package/src/Callout/Callout.figma.tsx +0 -25
  19. package/src/Callout/Callout.tsx +0 -43
  20. package/src/Callout/index.ts +0 -1
  21. package/src/Card/Card.css +0 -88
  22. package/src/Card/Card.figma.tsx +0 -28
  23. package/src/Card/Card.tsx +0 -60
  24. package/src/Card/index.ts +0 -1
  25. package/src/ChatInterface/ChatInterface.css +0 -50
  26. package/src/ChatInterface/ChatInterface.integration.test.tsx +0 -123
  27. package/src/ChatInterface/ChatInterface.tsx +0 -125
  28. package/src/ChatInterface/index.ts +0 -6
  29. package/src/ChatMessage/ChatMessage.css +0 -55
  30. package/src/ChatMessage/ChatMessage.tsx +0 -71
  31. package/src/ChatMessage/index.ts +0 -2
  32. package/src/ChatMessageList/ChatMessageList.css +0 -24
  33. package/src/ChatMessageList/ChatMessageList.test.tsx +0 -70
  34. package/src/ChatMessageList/ChatMessageList.tsx +0 -56
  35. package/src/ChatMessageList/index.ts +0 -2
  36. package/src/Checkbox/Checkbox.css +0 -97
  37. package/src/Checkbox/Checkbox.tsx +0 -70
  38. package/src/Checkbox/index.ts +0 -2
  39. package/src/CitationMark/CitationMark.css +0 -40
  40. package/src/CitationMark/CitationMark.tsx +0 -38
  41. package/src/CitationMark/index.ts +0 -2
  42. package/src/CitedExcerpt/CitedExcerpt.css +0 -75
  43. package/src/CitedExcerpt/CitedExcerpt.tsx +0 -53
  44. package/src/CitedExcerpt/index.ts +0 -2
  45. package/src/ComparisonTable/ComparisonTable.css +0 -66
  46. package/src/ComparisonTable/ComparisonTable.tsx +0 -54
  47. package/src/ComparisonTable/index.ts +0 -1
  48. package/src/ContactForm/ContactForm.css +0 -38
  49. package/src/ContactForm/ContactForm.tsx +0 -58
  50. package/src/ContactForm/index.ts +0 -1
  51. package/src/DataTable/DataTable.css +0 -56
  52. package/src/DataTable/DataTable.tsx +0 -104
  53. package/src/DataTable/index.ts +0 -2
  54. package/src/DocumentOverlay/DocumentOverlay.css +0 -57
  55. package/src/DocumentOverlay/DocumentOverlay.test.tsx +0 -95
  56. package/src/DocumentOverlay/DocumentOverlay.tsx +0 -87
  57. package/src/DocumentOverlay/index.ts +0 -2
  58. package/src/Footer/Footer.css +0 -72
  59. package/src/Footer/Footer.tsx +0 -59
  60. package/src/Footer/index.ts +0 -1
  61. package/src/FormField/FormField.css +0 -78
  62. package/src/FormField/FormField.figma.tsx +0 -28
  63. package/src/FormField/FormField.tsx +0 -103
  64. package/src/FormField/index.ts +0 -2
  65. package/src/HowStep/HowStep.css +0 -48
  66. package/src/HowStep/HowStep.figma.tsx +0 -23
  67. package/src/HowStep/HowStep.tsx +0 -38
  68. package/src/HowStep/index.ts +0 -1
  69. package/src/LogoMark/LogoMark.css +0 -16
  70. package/src/LogoMark/LogoMark.tsx +0 -24
  71. package/src/LogoMark/index.ts +0 -2
  72. package/src/Modal/Modal.css +0 -101
  73. package/src/Modal/Modal.figma.tsx +0 -28
  74. package/src/Modal/Modal.test.tsx +0 -46
  75. package/src/Modal/Modal.tsx +0 -144
  76. package/src/Modal/index.ts +0 -2
  77. package/src/Nav/Nav.css +0 -161
  78. package/src/Nav/Nav.tsx +0 -105
  79. package/src/Nav/index.ts +0 -1
  80. package/src/Panel/Panel.css +0 -35
  81. package/src/Panel/Panel.tsx +0 -61
  82. package/src/Panel/index.ts +0 -2
  83. package/src/PromptBar/PromptBar.css +0 -68
  84. package/src/PromptBar/PromptBar.figma.tsx +0 -25
  85. package/src/PromptBar/PromptBar.test.tsx +0 -83
  86. package/src/PromptBar/PromptBar.tsx +0 -93
  87. package/src/PromptBar/index.ts +0 -2
  88. package/src/RadioGroup/RadioGroup.css +0 -117
  89. package/src/RadioGroup/RadioGroup.tsx +0 -112
  90. package/src/RadioGroup/index.ts +0 -2
  91. package/src/SectionHeader/SectionHeader.css +0 -38
  92. package/src/SectionHeader/SectionHeader.figma.tsx +0 -23
  93. package/src/SectionHeader/SectionHeader.tsx +0 -55
  94. package/src/SectionHeader/index.ts +0 -1
  95. package/src/Select/Select.css +0 -90
  96. package/src/Select/Select.figma.tsx +0 -33
  97. package/src/Select/Select.tsx +0 -100
  98. package/src/Select/index.ts +0 -2
  99. package/src/SignalsPanel/SignalsPanel.css +0 -51
  100. package/src/SignalsPanel/SignalsPanel.tsx +0 -35
  101. package/src/SignalsPanel/index.ts +0 -1
  102. package/src/SuggestionCard/SuggestionCard.css +0 -51
  103. package/src/SuggestionCard/SuggestionCard.tsx +0 -34
  104. package/src/SuggestionCard/index.ts +0 -2
  105. package/src/SuggestionCards/SuggestionCards.css +0 -15
  106. package/src/SuggestionCards/SuggestionCards.test.tsx +0 -27
  107. package/src/SuggestionCards/SuggestionCards.tsx +0 -40
  108. package/src/SuggestionCards/index.ts +0 -2
  109. package/src/Toast/Toast.css +0 -85
  110. package/src/Toast/Toast.tsx +0 -82
  111. package/src/Toast/index.ts +0 -2
  112. package/src/Toggle/Toggle.css +0 -110
  113. package/src/Toggle/Toggle.figma.tsx +0 -24
  114. package/src/Toggle/Toggle.tsx +0 -73
  115. package/src/Toggle/index.ts +0 -2
  116. package/src/TypingIndicator/TypingIndicator.css +0 -70
  117. package/src/TypingIndicator/TypingIndicator.tsx +0 -37
  118. package/src/TypingIndicator/index.ts +0 -2
  119. package/src/index.ts +0 -39
  120. package/src/styles/utilities.css +0 -14
  121. package/src/styles.css +0 -33
  122. package/src/types.ts +0 -66
@@ -1,40 +0,0 @@
1
- /* Badge — @pcoi/components */
2
-
3
- .pcoi-badge {
4
- display: inline-flex;
5
- align-items: center;
6
- font-family: var(--pcoi-semantic-type-mono-font);
7
- font-size: var(--pcoi-semantic-type-badge-size);
8
- font-weight: var(--pcoi-semantic-type-label-weight);
9
- letter-spacing: var(--pcoi-semantic-type-badge-letter-spacing);
10
- text-transform: uppercase;
11
- padding: var(--pcoi-semantic-spacing-inline-2xs) var(--pcoi-semantic-spacing-chip-x);
12
- border-radius: var(--pcoi-semantic-radius-badge);
13
- line-height: var(--pcoi-semantic-type-none-line-height);
14
- }
15
-
16
- /* ── Variants ── */
17
- .pcoi-badge--default {
18
- background: var(--pcoi-semantic-surface-accent-dim);
19
- color: var(--pcoi-semantic-text-accent);
20
- }
21
-
22
- .pcoi-badge--success {
23
- background: var(--pcoi-semantic-action-success-bg);
24
- color: var(--pcoi-semantic-text-success);
25
- }
26
-
27
- .pcoi-badge--error {
28
- background: var(--pcoi-semantic-action-error-bg);
29
- color: var(--pcoi-semantic-text-error);
30
- }
31
-
32
- .pcoi-badge--warning {
33
- background: var(--pcoi-semantic-action-warning-bg);
34
- color: var(--pcoi-semantic-text-warning);
35
- }
36
-
37
- .pcoi-badge--info {
38
- background: var(--pcoi-semantic-action-info-bg);
39
- color: var(--pcoi-semantic-text-info);
40
- }
@@ -1,36 +0,0 @@
1
- import React from "react";
2
-
3
- export type BadgeVariant = "default" | "success" | "error" | "warning" | "info";
4
-
5
- export interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
6
- /** Badge content */
7
- children: React.ReactNode;
8
- /** Color variant */
9
- variant?: BadgeVariant;
10
- }
11
-
12
- /**
13
- * PCOI Badge — Small label for status indicators, categories, and counts
14
- * Tokens: surface/accent-dim, text/accent, text/success, text/error,
15
- * text/warning, text/info, radius-full, font-family/mono
16
- */
17
- export const Badge = React.forwardRef<HTMLSpanElement, BadgeProps>(
18
- ({ children, variant = "default", className = "", ...rest }, ref) => {
19
- const classes = [
20
- "pcoi-badge",
21
- `pcoi-badge--${variant}`,
22
- className,
23
- ]
24
- .filter(Boolean)
25
- .join(" ");
26
-
27
- return (
28
- <span ref={ref} className={classes} {...rest}>
29
- {children}
30
- </span>
31
- );
32
- }
33
- );
34
-
35
- Badge.displayName = "Badge";
36
- export default Badge;
@@ -1,2 +0,0 @@
1
- export { Badge, type BadgeProps, type BadgeVariant } from "./Badge";
2
- export { default } from "./Badge";
@@ -1,93 +0,0 @@
1
- /* Button — @pcoi/components
2
- All visual properties reference @pcoi/tokens semantic layer */
3
-
4
- .pcoi-btn {
5
- display: inline-flex;
6
- align-items: center;
7
- justify-content: center;
8
- padding: var(--pcoi-semantic-spacing-btn-y-comfortable) var(--pcoi-semantic-spacing-btn-x-comfortable);
9
- font-size: var(--pcoi-semantic-type-body-size); /* 0.95rem */
10
- font-weight: var(--pcoi-semantic-type-emphasis-weight);
11
- font-family: var(--pcoi-semantic-type-body-font);
12
- border-radius: var(--pcoi-semantic-radius-btn);
13
- border: none;
14
- cursor: pointer;
15
- transition: all var(--pcoi-effect-transition-fast, 0.2s ease);
16
- text-decoration: none;
17
- line-height: var(--pcoi-semantic-type-none-line-height);
18
- white-space: nowrap;
19
- }
20
-
21
- /* ── Primary ── */
22
- .pcoi-btn--primary {
23
- background: var(--pcoi-semantic-action-primary-bg);
24
- color: var(--pcoi-semantic-action-primary-text);
25
- }
26
-
27
- .pcoi-btn--primary:hover {
28
- background: var(--pcoi-semantic-action-primary-bg-hover);
29
- transform: var(--pcoi-effect-transform-hover-lift);
30
- box-shadow: var(--pcoi-effect-shadow-btn-primary-hover);
31
- }
32
-
33
- /* ── Ghost ── */
34
- .pcoi-btn--ghost {
35
- background: transparent;
36
- color: var(--pcoi-semantic-action-ghost-text);
37
- border: 1px solid var(--pcoi-semantic-action-ghost-border);
38
- }
39
-
40
- .pcoi-btn--ghost:hover {
41
- color: var(--pcoi-semantic-action-ghost-text-hover);
42
- border-color: var(--pcoi-semantic-action-ghost-border-hover);
43
- background: var(--pcoi-semantic-action-ghost-bg-hover);
44
- }
45
-
46
- /* ── Nav CTA ── */
47
- .pcoi-btn--nav-cta {
48
- background: var(--pcoi-semantic-action-primary-bg);
49
- color: var(--pcoi-semantic-action-primary-text);
50
- padding: var(--pcoi-semantic-spacing-btn-y) var(--pcoi-semantic-spacing-btn-x-nav);
51
- font-weight: var(--pcoi-semantic-type-emphasis-weight);
52
- }
53
-
54
- .pcoi-btn--nav-cta:hover {
55
- background: var(--pcoi-semantic-action-primary-bg-hover);
56
- transform: var(--pcoi-effect-transform-hover-lift-sm);
57
- }
58
-
59
- /* ── Press ── */
60
- .pcoi-btn--primary:active {
61
- transform: var(--pcoi-effect-transform-press-scale);
62
- box-shadow: none;
63
- }
64
-
65
- .pcoi-btn--ghost:active {
66
- transform: var(--pcoi-effect-transform-press-scale);
67
- }
68
-
69
- .pcoi-btn--nav-cta:active {
70
- transform: var(--pcoi-effect-transform-press-scale);
71
- box-shadow: none;
72
- }
73
-
74
- /* ── Focus ── */
75
- .pcoi-btn:focus-visible {
76
- outline: none;
77
- box-shadow: var(--pcoi-effect-shadow-focus-ring);
78
- }
79
-
80
- /* ── Disabled ── */
81
- .pcoi-btn:disabled,
82
- .pcoi-btn[aria-disabled="true"] {
83
- opacity: var(--pcoi-effect-opacity-disabled);
84
- cursor: not-allowed;
85
- transform: none;
86
- box-shadow: none;
87
- }
88
-
89
- /* ── Size: Large ── */
90
- .pcoi-btn--large {
91
- padding: var(--pcoi-semantic-spacing-btn-y-lg) var(--pcoi-semantic-spacing-btn-x-lg);
92
- font-size: var(--pcoi-semantic-type-body-lg-size); /* 1rem */
93
- }
@@ -1,27 +0,0 @@
1
- import figma from "@figma/code-connect";
2
- import { Button } from "./Button";
3
-
4
- /**
5
- * Code Connect: Button/Primary
6
- * Maps Figma Button component properties to React Button props
7
- */
8
- figma.connect(Button, "https://www.figma.com/file/PCOIxDesignSystem/PCOI-Design-System?node-id=101-1", {
9
- props: {
10
- variant: figma.enum("Variant", {
11
- Primary: "primary",
12
- Ghost: "ghost",
13
- "Nav CTA": "nav-cta",
14
- }),
15
- size: figma.enum("Size", {
16
- Default: "default",
17
- Large: "large",
18
- }),
19
- label: figma.string("Label"),
20
- disabled: figma.boolean("Disabled"),
21
- },
22
- example: ({ variant, size, label, disabled }) => (
23
- <Button variant={variant} size={size} disabled={disabled}>
24
- {label}
25
- </Button>
26
- ),
27
- });
@@ -1,32 +0,0 @@
1
- import { fireEvent, render, screen } from "@testing-library/react";
2
- import { describe, expect, it, vi } from "vitest";
3
- import { Button } from "./Button";
4
-
5
- describe("Button", () => {
6
- it("renders children with default variant classes", () => {
7
- render(<Button>Send</Button>);
8
-
9
- const button = screen.getByRole("button", { name: "Send" });
10
- expect(button).toHaveClass("pcoi-btn", "pcoi-btn--primary");
11
- expect(button).not.toHaveClass("pcoi-btn--large");
12
- });
13
-
14
- it("applies variant and size classes", () => {
15
- render(
16
- <Button variant="ghost" size="large">
17
- Cancel
18
- </Button>
19
- );
20
-
21
- const button = screen.getByRole("button", { name: "Cancel" });
22
- expect(button).toHaveClass("pcoi-btn--ghost", "pcoi-btn--large");
23
- });
24
-
25
- it("invokes onClick when enabled", () => {
26
- const onClick = vi.fn();
27
- render(<Button onClick={onClick}>Click</Button>);
28
-
29
- fireEvent.click(screen.getByRole("button", { name: "Click" }));
30
- expect(onClick).toHaveBeenCalledTimes(1);
31
- });
32
- });
@@ -1,47 +0,0 @@
1
- import React from "react";
2
-
3
- export type ButtonVariant = "primary" | "ghost" | "nav-cta";
4
- export type ButtonSize = "default" | "large";
5
-
6
- export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
7
- /** Visual variant */
8
- variant?: ButtonVariant;
9
- /** Size preset */
10
- size?: ButtonSize;
11
- /** Content */
12
- children: React.ReactNode;
13
- }
14
-
15
- /**
16
- * PCOI Button Component
17
- *
18
- * Variants:
19
- * - primary: Gold accent bg, dark text. Hero CTA, form submit.
20
- * - ghost: Transparent bg, subtle border. Secondary actions.
21
- * - nav-cta: Compact primary for navigation bar.
22
- *
23
- * Tokens consumed:
24
- * - action/primary-bg, action/primary-bg-hover, action/primary-text
25
- * - action/ghost-bg, action/ghost-border, action/ghost-text
26
- * - radius-sm, transition/fast
27
- * - shadow/btn-primary-hover, transform/hover-lift
28
- */
29
- export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
30
- ({ variant = "primary", size = "default", children, className = "", ...props }, ref) => {
31
- const classes = [
32
- "pcoi-btn",
33
- `pcoi-btn--${variant}`,
34
- size !== "default" ? `pcoi-btn--${size}` : "",
35
- className,
36
- ].filter(Boolean).join(" ");
37
-
38
- return (
39
- <button ref={ref} className={classes} {...props}>
40
- {children}
41
- </button>
42
- );
43
- }
44
- );
45
-
46
- Button.displayName = "Button";
47
- export default Button;
@@ -1 +0,0 @@
1
- export { Button, type ButtonProps, type ButtonVariant, type ButtonSize } from "./Button";
@@ -1,48 +0,0 @@
1
- /* Callout — @pcoi/components */
2
-
3
- .pcoi-callout {
4
- text-align: center;
5
- padding: var(--pcoi-semantic-spacing-component-gap) var(--pcoi-semantic-spacing-btn-x);
6
- display: flex;
7
- flex-direction: column;
8
- align-items: center;
9
- }
10
-
11
- .pcoi-callout__line {
12
- width: var(--pcoi-semantic-sizing-accent-line-width);
13
- height: 2px;
14
- background: var(--pcoi-semantic-text-accent);
15
- margin-bottom: var(--pcoi-semantic-spacing-stack-lg);
16
- }
17
-
18
- .pcoi-callout__quote {
19
- font-size: var(--pcoi-semantic-type-callout-size);
20
- font-weight: var(--pcoi-semantic-type-callout-weight);
21
- color: var(--pcoi-semantic-text-secondary);
22
- line-height: var(--pcoi-semantic-type-body-compact-line-height);
23
- max-width: var(--pcoi-semantic-sizing-callout-width, 640px);
24
- margin: 0 0 var(--pcoi-semantic-spacing-panel-padding) 0;
25
- padding: 0;
26
- font-style: italic;
27
- }
28
-
29
- .pcoi-callout__quote p {
30
- margin: 0;
31
- }
32
-
33
- .pcoi-callout__attribution {
34
- font-size: var(--pcoi-semantic-type-body-sm-size);
35
- color: var(--pcoi-semantic-text-muted);
36
- margin: 0;
37
- }
38
-
39
- .pcoi-callout__attribution a {
40
- color: var(--pcoi-semantic-text-accent);
41
- text-decoration: underline;
42
- text-underline-offset: 2px;
43
- transition: color var(--pcoi-effect-transition-fast, 0.2s ease);
44
- }
45
-
46
- .pcoi-callout__attribution a:hover {
47
- color: var(--pcoi-semantic-text-accent-hover);
48
- }
@@ -1,25 +0,0 @@
1
- import figma from "@figma/code-connect";
2
- import { Callout } from "./Callout";
3
-
4
- /**
5
- * Code Connect: Callout
6
- * Maps Figma callout content properties to React Callout props
7
- */
8
- figma.connect(Callout, "https://www.figma.com/file/PCOIxDesignSystem/PCOI-Design-System?node-id=108-1", {
9
- props: {
10
- quote: figma.string("Quote"),
11
- attribution: figma.string("Attribution"),
12
- attributionTitle: figma.string("Attribution Title"),
13
- sourceUrl: figma.string("Source URL"),
14
- sourceLabel: figma.string("Source Label"),
15
- },
16
- example: ({ quote, attribution, attributionTitle, sourceUrl, sourceLabel }) => (
17
- <Callout
18
- quote={quote}
19
- attribution={attribution || undefined}
20
- attributionTitle={attributionTitle || undefined}
21
- sourceUrl={sourceUrl || undefined}
22
- sourceLabel={sourceLabel || undefined}
23
- />
24
- ),
25
- });
@@ -1,43 +0,0 @@
1
- import React from "react";
2
-
3
- export interface CalloutProps extends React.HTMLAttributes<HTMLElement> {
4
- /** Quote text */
5
- quote: string;
6
- /** Attribution name */
7
- attribution?: string;
8
- /** Attribution title/context */
9
- attributionTitle?: string;
10
- /** Link URL for the source reference */
11
- sourceUrl?: string;
12
- /** Display label for the source link (default: "Source") */
13
- sourceLabel?: string;
14
- }
15
-
16
- /**
17
- * PCOI Callout / Blockquote
18
- *
19
- * Renders a semantic `<figure>` with `<blockquote>` and optional `<figcaption>`.
20
- * Tokens: spacing-40 (padding), text/secondary, text/accent (link)
21
- */
22
- export const Callout = React.forwardRef<HTMLElement, CalloutProps>(
23
- ({ quote, attribution, attributionTitle, sourceUrl, sourceLabel, className = "", ...rest }, ref) => (
24
- <figure ref={ref} className={`pcoi-callout ${className}`} {...rest}>
25
- <div className="pcoi-callout__line" aria-hidden="true" />
26
- <blockquote className="pcoi-callout__quote">
27
- <p>{quote}</p>
28
- </blockquote>
29
- {(attribution || sourceUrl) && (
30
- <figcaption className="pcoi-callout__attribution">
31
- {attributionTitle && <span>{attributionTitle} &nbsp;~&nbsp; </span>}
32
- {attribution}
33
- {sourceUrl && (
34
- <> &nbsp;|&nbsp; <a href={sourceUrl} target="_blank" rel="noopener noreferrer">{sourceLabel || "Source"}</a></>
35
- )}
36
- </figcaption>
37
- )}
38
- </figure>
39
- )
40
- );
41
-
42
- Callout.displayName = "Callout";
43
- export default Callout;
@@ -1 +0,0 @@
1
- export { Callout, type CalloutProps } from "./Callout";
package/src/Card/Card.css DELETED
@@ -1,88 +0,0 @@
1
- /* Card — @pcoi/components */
2
-
3
- .pcoi-card {
4
- border: 1px solid var(--pcoi-semantic-border-card);
5
- border-radius: var(--pcoi-semantic-radius-card);
6
- padding: var(--pcoi-semantic-spacing-card-padding);
7
- transition: border-color var(--pcoi-effect-transition-medium, 0.3s ease),
8
- transform var(--pcoi-effect-transition-medium, 0.3s ease);
9
- }
10
-
11
- .pcoi-card:hover {
12
- border-color: var(--pcoi-semantic-border-card-hover);
13
- transform: var(--pcoi-effect-transform-hover-lift);
14
- }
15
-
16
- /* ── Problem Card ── */
17
- .pcoi-card--problem {
18
- background: var(--pcoi-semantic-bg-card);
19
- }
20
-
21
- .pcoi-card--problem .pcoi-card__icon {
22
- width: var(--pcoi-semantic-sizing-icon-box);
23
- height: var(--pcoi-semantic-sizing-icon-box);
24
- border-radius: var(--pcoi-semantic-radius-btn);
25
- background: var(--pcoi-semantic-surface-accent-dim);
26
- display: flex;
27
- align-items: center;
28
- justify-content: center;
29
- margin-bottom: var(--pcoi-semantic-spacing-card-gap);
30
- color: var(--pcoi-semantic-text-accent);
31
- }
32
-
33
- .pcoi-card--problem .pcoi-card__title {
34
- font-size: var(--pcoi-semantic-type-heading-md-size);
35
- font-weight: var(--pcoi-semantic-type-emphasis-weight);
36
- color: var(--pcoi-semantic-text-primary);
37
- margin: 0 0 var(--pcoi-semantic-spacing-text-gap-sm) 0;
38
- }
39
-
40
- .pcoi-card--problem .pcoi-card__description {
41
- font-size: var(--pcoi-semantic-type-body-size);
42
- color: var(--pcoi-semantic-text-secondary);
43
- line-height: var(--pcoi-semantic-type-body-line-height);
44
- }
45
-
46
- /* ── Who Card ── */
47
- .pcoi-card--who {
48
- background: var(--pcoi-semantic-bg-surface);
49
- }
50
-
51
- .pcoi-card--who .pcoi-card__title {
52
- font-size: var(--pcoi-semantic-type-heading-sm-size);
53
- font-weight: var(--pcoi-semantic-type-emphasis-weight);
54
- color: var(--pcoi-semantic-text-accent);
55
- margin: 0 0 var(--pcoi-semantic-spacing-text-gap-sm) 0;
56
- }
57
-
58
- .pcoi-card--who .pcoi-card__description {
59
- font-size: var(--pcoi-semantic-type-body-compact-size);
60
- color: var(--pcoi-semantic-text-secondary);
61
- line-height: var(--pcoi-semantic-type-body-line-height);
62
- }
63
-
64
- /* ── Principle Card ── */
65
- .pcoi-card--principle {
66
- background: var(--pcoi-semantic-bg-card);
67
- }
68
-
69
- .pcoi-card--principle .pcoi-card__number {
70
- font-family: var(--pcoi-semantic-type-mono-font);
71
- font-size: var(--pcoi-semantic-type-body-sm-size);
72
- font-weight: var(--pcoi-semantic-type-emphasis-weight);
73
- color: var(--pcoi-semantic-text-accent);
74
- margin-bottom: var(--pcoi-semantic-spacing-stack-md);
75
- }
76
-
77
- .pcoi-card--principle .pcoi-card__title {
78
- font-size: var(--pcoi-semantic-type-card-subtitle-size);
79
- font-weight: var(--pcoi-semantic-type-emphasis-weight);
80
- color: var(--pcoi-semantic-text-primary);
81
- margin: 0 0 var(--pcoi-semantic-spacing-text-gap-sm) 0;
82
- }
83
-
84
- .pcoi-card--principle .pcoi-card__description {
85
- font-size: var(--pcoi-semantic-type-body-compact-size);
86
- color: var(--pcoi-semantic-text-secondary);
87
- line-height: var(--pcoi-semantic-type-body-line-height);
88
- }
@@ -1,28 +0,0 @@
1
- import figma from "@figma/code-connect";
2
- import { Card } from "./Card";
3
-
4
- /**
5
- * Code Connect: Card
6
- * Maps Figma Card component properties to React Card props
7
- */
8
- figma.connect(Card, "https://www.figma.com/file/PCOIxDesignSystem/PCOI-Design-System?node-id=102-1", {
9
- props: {
10
- variant: figma.enum("Variant", {
11
- Problem: "problem",
12
- Who: "who",
13
- Principle: "principle",
14
- }),
15
- title: figma.string("Title"),
16
- description: figma.string("Description"),
17
- number: figma.string("Number"),
18
- },
19
- example: ({ variant, title, description, number }) => (
20
- <Card
21
- variant={variant}
22
- title={title}
23
- description={description}
24
- number={number}
25
- icon={variant === "problem" ? <span aria-hidden="true">!</span> : undefined}
26
- />
27
- ),
28
- });
package/src/Card/Card.tsx DELETED
@@ -1,60 +0,0 @@
1
- import React from "react";
2
- import type { HeadingLevel } from "../types";
3
-
4
- export type CardVariant = "problem" | "who" | "principle";
5
-
6
- export interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
7
- /** Card visual variant */
8
- variant?: CardVariant;
9
- /** Card title */
10
- title: string;
11
- /** Card body text */
12
- description: string;
13
- /** Icon element (for problem cards) */
14
- icon?: React.ReactNode;
15
- /** Roman numeral or number (for principle cards) */
16
- number?: string;
17
- /** Heading level for the title (default: "h3") */
18
- headingLevel?: HeadingLevel;
19
- }
20
-
21
- /**
22
- * PCOI Card Component
23
- *
24
- * Three variants extracted from pcoi.ai:
25
- * - problem: bg-card, icon box + title + description (Problem section)
26
- * - who: surface bg, accent title (Who It's For section)
27
- * - principle: bg-card, roman numeral + title + description (Principles section)
28
- *
29
- * Tokens consumed:
30
- * - bg/card, bg/surface, border/default, border/hover
31
- * - radius-md, spacing-36 (padding), spacing-20 (icon margin)
32
- * - text/primary, text/secondary, text/accent
33
- * - transition/medium, transform/hover-lift
34
- */
35
- export const Card = React.forwardRef<HTMLDivElement, CardProps>(
36
- ({ variant = "problem", title, description, icon, number, headingLevel = "h3", className = "", ...rest }, ref) => {
37
- const Heading = headingLevel;
38
- const classes = [
39
- "pcoi-card",
40
- `pcoi-card--${variant}`,
41
- className,
42
- ].filter(Boolean).join(" ");
43
-
44
- return (
45
- <div ref={ref} className={classes} {...rest}>
46
- {variant === "problem" && icon && (
47
- <div className="pcoi-card__icon">{icon}</div>
48
- )}
49
- {variant === "principle" && number && (
50
- <div className="pcoi-card__number">{number}</div>
51
- )}
52
- <Heading className="pcoi-card__title">{title}</Heading>
53
- <p className="pcoi-card__description">{description}</p>
54
- </div>
55
- );
56
- }
57
- );
58
-
59
- Card.displayName = "Card";
60
- export default Card;
package/src/Card/index.ts DELETED
@@ -1 +0,0 @@
1
- export { Card, type CardProps, type CardVariant } from "./Card";
@@ -1,50 +0,0 @@
1
- /* ChatInterface — @pcoi/components */
2
-
3
- .pcoi-chat {
4
- display: flex;
5
- flex-direction: column;
6
- width: 100%;
7
- height: 100%;
8
- max-width: var(--pcoi-semantic-sizing-container-narrow, 800px);
9
- margin: 0 auto;
10
- }
11
-
12
- /* ── Empty state ── */
13
- .pcoi-chat--empty {
14
- justify-content: flex-end;
15
- }
16
-
17
- .pcoi-chat__empty-state {
18
- flex: 1;
19
- display: flex;
20
- flex-direction: column;
21
- justify-content: center;
22
- padding: var(--pcoi-semantic-spacing-panel-padding-sm);
23
- }
24
-
25
- .pcoi-chat__suggestions {
26
- max-width: 100%;
27
- }
28
-
29
- /* ── Messages ── */
30
- .pcoi-chat__messages {
31
- flex: 1;
32
- min-height: 0;
33
- }
34
-
35
- /* ── Prompt ── */
36
- .pcoi-chat__prompt {
37
- flex-shrink: 0;
38
- padding: var(--pcoi-semantic-spacing-panel-padding-sm);
39
- }
40
-
41
- /* ── Responsive ── */
42
- @media (min-width: 768px) {
43
- .pcoi-chat__empty-state {
44
- padding: var(--pcoi-semantic-spacing-panel-padding);
45
- }
46
-
47
- .pcoi-chat__prompt {
48
- padding: var(--pcoi-semantic-spacing-panel-padding);
49
- }
50
- }