@hraness/design-kit 0.34.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.
- package/README.md +16 -2
- package/dist/{chunk-mr1vdcjq.js → chunk-8xfssb9c.js} +6 -3
- package/dist/{chunk-nwpcjm48.js → chunk-c9mhn3yb.js} +1115 -441
- package/dist/{chunk-h4k7yv6x.js → chunk-fjf81bww.js} +28 -2
- package/dist/chunk-gmea6p0d.js +13 -0
- package/dist/index.js +5 -1
- package/dist/mockups/client.js +50 -15
- package/dist/portfolio.js +586 -85
- package/dist/react/index.js +137 -13
- package/dist/react/platform-install.js +3 -2
- package/dist/react/server.js +17 -3
- package/dist/stylex-manifest.json +1 -1
- package/dist/stylex.css +350 -32
- package/package.json +14 -3
- package/portfolio-inventory.json +1 -1
- package/src/diagrams.ts +11 -0
- package/src/index.ts +2 -0
- package/src/marketing-comparison.css +162 -0
- package/src/marketing-diagram.css +24 -0
- package/src/mockups/client.tsx +25 -17
- package/src/mockups.css +19 -0
- package/src/plain-publication.css +9 -6
- package/src/portfolio.generated.json +578 -86
- package/src/portfolio.generated.ts +578 -86
- package/src/portfolio.ts +73 -0
- package/src/product-marketing-foundation.css +29 -0
- package/src/product-marketing.css +133 -38
- package/src/react/article.tsx +2 -2
- package/src/react/design-gallery.tsx +33 -6
- package/src/react/index.ts +3 -0
- package/src/react/marketing-account.stylex.ts +74 -0
- package/src/react/marketing-account.tsx +69 -0
- package/src/react/marketing-comparison.stylex.ts +24 -0
- package/src/react/marketing-comparison.tsx +73 -0
- package/src/react/marketing-diagram.stylex.ts +8 -0
- package/src/react/marketing-diagram.tsx +33 -0
- package/src/react/platform-install.stylex.ts +2 -1
- package/src/react/platform-install.tsx +2 -1
- package/src/react/product-marketing.stylex.ts +138 -109
- package/src/react/product-marketing.tsx +69 -43
- package/src/react/server.ts +3 -0
- package/src/styles.css +2 -0
- package/src/typography.css +32 -0
- /package/dist/{chunk-4d79eskk.js → chunk-c80g58j1.js} +0 -0
|
@@ -546,6 +546,8 @@ export interface ProductHeroProps {
|
|
|
546
546
|
readonly heading: string;
|
|
547
547
|
readonly headingId: string;
|
|
548
548
|
readonly headingLevel?: MarketingHeadingLevel;
|
|
549
|
+
/** An install command or installer selector directly below the summary. */
|
|
550
|
+
readonly install?: ReactNode;
|
|
549
551
|
readonly name: string;
|
|
550
552
|
/** Product-owned notice after the copy boundary, without an added wrapper. */
|
|
551
553
|
readonly notice?: ReactNode;
|
|
@@ -571,6 +573,7 @@ export function ProductHero({
|
|
|
571
573
|
heading,
|
|
572
574
|
headingId,
|
|
573
575
|
headingLevel = 1,
|
|
576
|
+
install,
|
|
574
577
|
name,
|
|
575
578
|
notice,
|
|
576
579
|
proof,
|
|
@@ -587,11 +590,12 @@ export function ProductHero({
|
|
|
587
590
|
>
|
|
588
591
|
<div className={classNames("hraness-marketing-hero__copy", undefined, align === "start" ? "start" : "default")}>
|
|
589
592
|
{eyebrow === undefined || eyebrow === "" ? null : <p className={classNames("hraness-marketing-hero__eyebrow", undefined, tone === "accent" ? "accent" : "default")}>{eyebrow}</p>}
|
|
590
|
-
<p className={classNames("hraness-marketing-hero__name")}>{name}</p>
|
|
593
|
+
{name === "" ? null : <p className={classNames("hraness-marketing-hero__name")}>{name}</p>}
|
|
591
594
|
<Heading className={classNames("hraness-marketing-hero__heading")} id={headingId} level={headingLevel}>
|
|
592
595
|
{heading}
|
|
593
596
|
</Heading>
|
|
594
597
|
<p className={classNames("hraness-marketing-hero__summary")}>{summary}</p>
|
|
598
|
+
{install === undefined ? null : <div className={classNames("hraness-marketing-hero__install")}>{install}</div>}
|
|
595
599
|
{example === undefined
|
|
596
600
|
? null
|
|
597
601
|
: <p className={classNames("hraness-marketing-hero__example")}>{example}</p>}
|
|
@@ -627,6 +631,7 @@ export function ProductHero({
|
|
|
627
631
|
}
|
|
628
632
|
|
|
629
633
|
export interface MarketingPillar {
|
|
634
|
+
readonly icon?: ReactNode;
|
|
630
635
|
readonly label: string;
|
|
631
636
|
readonly summary: string;
|
|
632
637
|
}
|
|
@@ -636,25 +641,28 @@ export function MarketingPillars({
|
|
|
636
641
|
className,
|
|
637
642
|
columns,
|
|
638
643
|
pillars,
|
|
644
|
+
presentation = "columns",
|
|
639
645
|
}: Readonly<{
|
|
640
646
|
ariaLabel: string;
|
|
641
647
|
className?: string;
|
|
642
648
|
/** Static desktop columns without inline styles; omission uses the collection length. Mobile stays one column. */
|
|
643
649
|
columns?: MarketingColumnCount;
|
|
644
650
|
pillars: readonly MarketingPillar[];
|
|
651
|
+
presentation?: "columns" | "benefits";
|
|
645
652
|
}>) {
|
|
646
|
-
const rootClassName = marketingColumnClassName("hraness-marketing-pillars", className, columns);
|
|
653
|
+
const rootClassName = marketingColumnClassName("hraness-marketing-pillars", className, columns, presentation === "benefits" ? "benefits" : "default");
|
|
647
654
|
if (pillars.length === 0) return null;
|
|
648
655
|
return (
|
|
649
656
|
<dl
|
|
650
657
|
aria-label={ariaLabel}
|
|
651
658
|
className={rootClassName}
|
|
652
659
|
data-hraness-marketing="pillars"
|
|
660
|
+
data-presentation={presentation}
|
|
653
661
|
style={columns === undefined ? { "--hraness-marketing-pillar-columns": String(pillars.length) } as Record<string, string> : undefined}
|
|
654
662
|
>
|
|
655
663
|
{pillars.map((pillar, index) => (
|
|
656
|
-
<div className={classNames("hraness-marketing-pillars__item", undefined, index === 0 ? "default" : "later")} key={pillar.label}>
|
|
657
|
-
<dt className={classNames("hraness-marketing-pillars__label")}>{pillar.label}</dt>
|
|
664
|
+
<div className={classNames("hraness-marketing-pillars__item", undefined, presentation === "benefits" ? "benefit" : index === 0 ? "default" : "later")} key={pillar.label}>
|
|
665
|
+
<dt className={classNames("hraness-marketing-pillars__label")}>{pillar.icon === undefined ? null : <span aria-hidden="true" className={classNames("hraness-marketing-pillars__icon")}>{pillar.icon}</span>}{pillar.label}</dt>
|
|
658
666
|
<dd className={classNames("hraness-marketing-pillars__summary")}>{pillar.summary}</dd>
|
|
659
667
|
</div>
|
|
660
668
|
))}
|
|
@@ -1487,8 +1495,10 @@ export function MarketingMaker({
|
|
|
1487
1495
|
}
|
|
1488
1496
|
|
|
1489
1497
|
export interface MarketingRelatedProduct {
|
|
1490
|
-
/** Custom artwork in place of `mark`, drawn in the same
|
|
1498
|
+
/** Custom artwork in place of `mark`, drawn in the same 28px slot. */
|
|
1491
1499
|
readonly art?: ReactNode;
|
|
1500
|
+
/** Optional public host, displayed beside the product name. */
|
|
1501
|
+
readonly domain?: string;
|
|
1492
1502
|
readonly href: string;
|
|
1493
1503
|
/** Transparent product mark, such as a portfolio item's `mark`; drawn as a foil mark before the name. */
|
|
1494
1504
|
readonly mark?: string;
|
|
@@ -1502,6 +1512,8 @@ export interface MarketingRelatedProduct {
|
|
|
1502
1512
|
readonly role: string;
|
|
1503
1513
|
}
|
|
1504
1514
|
|
|
1515
|
+
export type MarketingRelatedTone = "rose" | "indigo" | "amber" | "emerald" | "neutral";
|
|
1516
|
+
|
|
1505
1517
|
export interface MarketingRelatedGroup {
|
|
1506
1518
|
/** Maximum columns for this group, overriding the section default. */
|
|
1507
1519
|
readonly columns?: MarketingColumnCount;
|
|
@@ -1510,33 +1522,44 @@ export interface MarketingRelatedGroup {
|
|
|
1510
1522
|
readonly headingId: string;
|
|
1511
1523
|
readonly items: readonly MarketingRelatedProduct[];
|
|
1512
1524
|
readonly summary?: string;
|
|
1525
|
+
/** The category color used on the studio portfolio. */
|
|
1526
|
+
readonly tone?: MarketingRelatedTone;
|
|
1513
1527
|
}
|
|
1514
1528
|
|
|
1515
1529
|
function MarketingRelatedCards({
|
|
1530
|
+
ariaLabel,
|
|
1531
|
+
columns,
|
|
1516
1532
|
items,
|
|
1517
1533
|
level,
|
|
1518
1534
|
}: Readonly<{
|
|
1535
|
+
ariaLabel?: string;
|
|
1536
|
+
columns?: MarketingColumnCount;
|
|
1519
1537
|
items: readonly MarketingRelatedProduct[];
|
|
1520
1538
|
level: MarketingHeadingLevel;
|
|
1521
1539
|
}>) {
|
|
1522
1540
|
return (
|
|
1523
|
-
|
|
1541
|
+
<ul aria-label={ariaLabel} className={marketingColumnClassName("hraness-marketing-related__list", undefined, columns)}>
|
|
1524
1542
|
{items.map((item) => (
|
|
1525
|
-
<
|
|
1526
|
-
{
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
<
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1543
|
+
<li className={classNames("hraness-marketing-related__item")} key={item.name}>
|
|
1544
|
+
<a className={classNames("hraness-marketing-related__card")} data-foil="" data-hraness-marketing="card" href={item.href}>
|
|
1545
|
+
{isPresentNode(item.art) || (item.mark !== undefined && item.mark !== "")
|
|
1546
|
+
? (
|
|
1547
|
+
<span aria-hidden="true" className={classNames("hraness-marketing-related__card-mark")}>
|
|
1548
|
+
{isPresentNode(item.art) ? item.art : <FoilMark size={28} src={item.mark ?? ""} />}
|
|
1549
|
+
</span>
|
|
1550
|
+
)
|
|
1551
|
+
: null}
|
|
1552
|
+
<div className={classNames("hraness-marketing-related__card-text")}>
|
|
1553
|
+
<div className={classNames("hraness-marketing-related__card-heading")}>
|
|
1554
|
+
<Heading className={classNames("hraness-marketing-related__card-name")} level={level}>{item.name}</Heading>
|
|
1555
|
+
{item.domain === undefined ? null : <span className={classNames("hraness-marketing-related__card-domain")}>{item.domain}</span>}
|
|
1556
|
+
</div>
|
|
1557
|
+
<span className={classNames("hraness-marketing-related__card-role")}>{item.role}</span>
|
|
1558
|
+
</div>
|
|
1559
|
+
</a>
|
|
1560
|
+
</li>
|
|
1538
1561
|
))}
|
|
1539
|
-
|
|
1562
|
+
</ul>
|
|
1540
1563
|
);
|
|
1541
1564
|
}
|
|
1542
1565
|
|
|
@@ -1544,7 +1567,7 @@ type MarketingRelatedBody =
|
|
|
1544
1567
|
| Readonly<{ groups: readonly MarketingRelatedGroup[]; items?: undefined }>
|
|
1545
1568
|
| Readonly<{ groups?: undefined; items: readonly MarketingRelatedProduct[] }>;
|
|
1546
1569
|
|
|
1547
|
-
/**
|
|
1570
|
+
/** Compact studio product rows, grouped by portfolio category when supplied. */
|
|
1548
1571
|
export function MarketingRelated({
|
|
1549
1572
|
className,
|
|
1550
1573
|
columns,
|
|
@@ -1585,30 +1608,33 @@ export function MarketingRelated({
|
|
|
1585
1608
|
summary={summary}
|
|
1586
1609
|
/>
|
|
1587
1610
|
{groups === undefined
|
|
1588
|
-
? (
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
className={classNames("hraness-marketing-related__group-heading")}
|
|
1598
|
-
id={group.headingId}
|
|
1599
|
-
level={childHeadingLevel(headingLevel)}
|
|
1611
|
+
? <MarketingRelatedCards {...defaultColumnProps} items={items} level={childHeadingLevel(headingLevel)} />
|
|
1612
|
+
: (
|
|
1613
|
+
<div className={classNames("hraness-marketing-related__groups")}>
|
|
1614
|
+
{groups.map((group) => (
|
|
1615
|
+
<div
|
|
1616
|
+
aria-labelledby={group.headingId}
|
|
1617
|
+
className={classNames("hraness-marketing-related__group", undefined, group.tone ?? "neutral")}
|
|
1618
|
+
data-tone={group.tone ?? "neutral"}
|
|
1619
|
+
key={group.headingId}
|
|
1600
1620
|
>
|
|
1601
|
-
{
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1621
|
+
<div className={classNames("hraness-marketing-related__group-header")}>
|
|
1622
|
+
<Heading
|
|
1623
|
+
className={classNames("hraness-marketing-related__group-heading")}
|
|
1624
|
+
id={group.headingId}
|
|
1625
|
+
level={childHeadingLevel(headingLevel)}
|
|
1626
|
+
>
|
|
1627
|
+
{group.heading}
|
|
1628
|
+
</Heading>
|
|
1629
|
+
{group.summary === undefined
|
|
1630
|
+
? null
|
|
1631
|
+
: <p className={classNames("hraness-marketing-related__group-summary")}>{group.summary}</p>}
|
|
1632
|
+
</div>
|
|
1633
|
+
<MarketingRelatedCards ariaLabel={group.heading} {...(group.columns === undefined ? defaultColumnProps : { columns: group.columns })} items={group.items} level={childHeadingLevel(childHeadingLevel(headingLevel))} />
|
|
1634
|
+
</div>
|
|
1635
|
+
))}
|
|
1610
1636
|
</div>
|
|
1611
|
-
)
|
|
1637
|
+
)}
|
|
1612
1638
|
</section>
|
|
1613
1639
|
);
|
|
1614
1640
|
}
|
package/src/react/server.ts
CHANGED
|
@@ -3,9 +3,12 @@ export * from "./particle-halo.js";
|
|
|
3
3
|
export * from "./procedural-backdrop.js";
|
|
4
4
|
export * from "./procedural-recipe.js";
|
|
5
5
|
export * from "./product-marketing.js";
|
|
6
|
+
export * from "./marketing-account.js";
|
|
7
|
+
export * from "./marketing-comparison.js";
|
|
6
8
|
export * from "./surfaces.js";
|
|
7
9
|
export * from "./syntax-code.js";
|
|
8
10
|
export * from "./foil-mark.js";
|
|
9
11
|
export * from "./provider-mark.js";
|
|
10
12
|
export * from "./platform-icons.js";
|
|
11
13
|
export * from "./launch-beats.js";
|
|
14
|
+
export * from "./marketing-diagram.js";
|
package/src/styles.css
CHANGED
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
@import "./charts.css";
|
|
13
13
|
@import "./plain-site.css";
|
|
14
14
|
@import "./plain-publication.css";
|
|
15
|
+
@import "./marketing-comparison.css";
|
|
16
|
+
@import "./marketing-diagram.css";
|
|
15
17
|
@import "./reading.css";
|
|
16
18
|
@import "./status-page.css";
|
|
17
19
|
@import "./product-marketing.css";
|
package/src/typography.css
CHANGED
|
@@ -11,6 +11,12 @@
|
|
|
11
11
|
* face. */
|
|
12
12
|
@layer base {
|
|
13
13
|
:root {
|
|
14
|
+
/* Shared studio category accents. Text names retain the foreground role. */
|
|
15
|
+
--hraness-studio-rose: light-dark(#b03a5b, #f39cb5);
|
|
16
|
+
--hraness-studio-indigo: light-dark(#4a4fbf, #a9adff);
|
|
17
|
+
--hraness-studio-amber: light-dark(#9a5a00, #f0b659);
|
|
18
|
+
--hraness-studio-emerald: light-dark(#1d7a55, #71d2a6);
|
|
19
|
+
|
|
14
20
|
--hraness-type-reading-size: clamp(1rem, .95rem + .25vw, 1.0625rem);
|
|
15
21
|
--hraness-type-reading-leading: 1.7;
|
|
16
22
|
--hraness-type-reading-measure: 70ch;
|
|
@@ -84,3 +90,29 @@
|
|
|
84
90
|
-webkit-text-fill-color: currentColor;
|
|
85
91
|
}
|
|
86
92
|
}
|
|
93
|
+
|
|
94
|
+
/* Prose and secondary text actions share a quiet, persistent link affordance. */
|
|
95
|
+
.hraness-text-link,
|
|
96
|
+
.hraness-prose :where(a:not([role="button"], [data-emphasis], [data-foil])),
|
|
97
|
+
.plain-publication__article-body :where(a:not([role="button"], [data-emphasis], [data-foil])),
|
|
98
|
+
.plain-page :where(p, li, dd, dt, figcaption) a:not([role="button"], [data-emphasis], [data-foil]) {
|
|
99
|
+
text-decoration-line: underline;
|
|
100
|
+
text-decoration-style: dotted;
|
|
101
|
+
text-decoration-color: color-mix(in srgb, currentColor 40%, transparent);
|
|
102
|
+
text-decoration-thickness: 1px;
|
|
103
|
+
text-underline-offset: 0.2em;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.hraness-text-link:is(:hover, :focus-visible),
|
|
107
|
+
.hraness-prose :where(a:not([role="button"], [data-emphasis], [data-foil])):is(:hover, :focus-visible),
|
|
108
|
+
.plain-page :where(p, li, dd, dt, figcaption) a:not([role="button"], [data-emphasis], [data-foil]):is(:hover, :focus-visible) {
|
|
109
|
+
text-decoration-color: currentColor;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
@media (forced-colors: active) {
|
|
113
|
+
.hraness-text-link,
|
|
114
|
+
.hraness-prose :where(a),
|
|
115
|
+
.plain-page :where(p, li, dd, dt, figcaption) a {
|
|
116
|
+
text-decoration-color: LinkText;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
File without changes
|