@hraness/design-kit 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.
- package/README.md +19 -3
- package/dist/{chunk-mr1vdcjq.js → chunk-8xfssb9c.js} +6 -3
- package/dist/{chunk-95mpmzc9.js → chunk-c9mhn3yb.js} +1130 -442
- 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 +141 -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 -36
- 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 +136 -39
- package/src/react/article.tsx +2 -2
- package/src/react/design-gallery.tsx +37 -8
- 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 +144 -111
- package/src/react/product-marketing.tsx +83 -45
- 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
|
))}
|
|
@@ -1148,6 +1156,7 @@ export interface MarketingInterface {
|
|
|
1148
1156
|
|
|
1149
1157
|
export function MarketingInterfaceGrid({
|
|
1150
1158
|
className,
|
|
1159
|
+
columns,
|
|
1151
1160
|
heading,
|
|
1152
1161
|
headingId,
|
|
1153
1162
|
headingLevel = 2,
|
|
@@ -1157,6 +1166,8 @@ export function MarketingInterfaceGrid({
|
|
|
1157
1166
|
summary,
|
|
1158
1167
|
}: Readonly<{
|
|
1159
1168
|
className?: string;
|
|
1169
|
+
/** Maximum columns; cards wrap within the available container width. */
|
|
1170
|
+
columns?: MarketingColumnCount;
|
|
1160
1171
|
heading: string;
|
|
1161
1172
|
headingId: string;
|
|
1162
1173
|
headingLevel?: MarketingHeadingLevel;
|
|
@@ -1173,7 +1184,7 @@ export function MarketingInterfaceGrid({
|
|
|
1173
1184
|
id={id}
|
|
1174
1185
|
>
|
|
1175
1186
|
<MarketingCollectionHeader {...{ heading, headingId, headingLevel, label, summary }} prefix="interfaces" />
|
|
1176
|
-
<div className={
|
|
1187
|
+
<div className={marketingColumnClassName("hraness-marketing-interface-grid", undefined, columns)}>
|
|
1177
1188
|
{interfaces.map((entry) => (
|
|
1178
1189
|
<article className={classNames("hraness-marketing-interface")} key={entry.label}>
|
|
1179
1190
|
<Heading
|
|
@@ -1198,6 +1209,7 @@ export interface MarketingTrustItem {
|
|
|
1198
1209
|
|
|
1199
1210
|
export function MarketingTrustBoundary({
|
|
1200
1211
|
className,
|
|
1212
|
+
columns,
|
|
1201
1213
|
heading,
|
|
1202
1214
|
headingId,
|
|
1203
1215
|
headingLevel = 2,
|
|
@@ -1207,6 +1219,8 @@ export function MarketingTrustBoundary({
|
|
|
1207
1219
|
summary,
|
|
1208
1220
|
}: Readonly<{
|
|
1209
1221
|
className?: string;
|
|
1222
|
+
/** Maximum columns; cards wrap within the available container width. */
|
|
1223
|
+
columns?: MarketingColumnCount;
|
|
1210
1224
|
heading: string;
|
|
1211
1225
|
headingId: string;
|
|
1212
1226
|
headingLevel?: MarketingHeadingLevel;
|
|
@@ -1223,7 +1237,7 @@ export function MarketingTrustBoundary({
|
|
|
1223
1237
|
id={id}
|
|
1224
1238
|
>
|
|
1225
1239
|
<MarketingCollectionHeader {...{ heading, headingId, headingLevel, label, summary }} prefix="trust" />
|
|
1226
|
-
<dl className={
|
|
1240
|
+
<dl className={marketingColumnClassName("hraness-marketing-trust-grid", undefined, columns)}>
|
|
1227
1241
|
{items.map((item) => (
|
|
1228
1242
|
<div className={classNames("hraness-marketing-trust-item")} key={item.label}>
|
|
1229
1243
|
<dt className={classNames("hraness-marketing-trust-item__label")}>{item.label}</dt>
|
|
@@ -1481,8 +1495,10 @@ export function MarketingMaker({
|
|
|
1481
1495
|
}
|
|
1482
1496
|
|
|
1483
1497
|
export interface MarketingRelatedProduct {
|
|
1484
|
-
/** Custom artwork in place of `mark`, drawn in the same
|
|
1498
|
+
/** Custom artwork in place of `mark`, drawn in the same 28px slot. */
|
|
1485
1499
|
readonly art?: ReactNode;
|
|
1500
|
+
/** Optional public host, displayed beside the product name. */
|
|
1501
|
+
readonly domain?: string;
|
|
1486
1502
|
readonly href: string;
|
|
1487
1503
|
/** Transparent product mark, such as a portfolio item's `mark`; drawn as a foil mark before the name. */
|
|
1488
1504
|
readonly mark?: string;
|
|
@@ -1496,39 +1512,54 @@ export interface MarketingRelatedProduct {
|
|
|
1496
1512
|
readonly role: string;
|
|
1497
1513
|
}
|
|
1498
1514
|
|
|
1515
|
+
export type MarketingRelatedTone = "rose" | "indigo" | "amber" | "emerald" | "neutral";
|
|
1516
|
+
|
|
1499
1517
|
export interface MarketingRelatedGroup {
|
|
1518
|
+
/** Maximum columns for this group, overriding the section default. */
|
|
1519
|
+
readonly columns?: MarketingColumnCount;
|
|
1500
1520
|
/** Heading naming this tier of siblings, rendered one level below the section heading. */
|
|
1501
1521
|
readonly heading: string;
|
|
1502
1522
|
readonly headingId: string;
|
|
1503
1523
|
readonly items: readonly MarketingRelatedProduct[];
|
|
1504
1524
|
readonly summary?: string;
|
|
1525
|
+
/** The category color used on the studio portfolio. */
|
|
1526
|
+
readonly tone?: MarketingRelatedTone;
|
|
1505
1527
|
}
|
|
1506
1528
|
|
|
1507
1529
|
function MarketingRelatedCards({
|
|
1530
|
+
ariaLabel,
|
|
1531
|
+
columns,
|
|
1508
1532
|
items,
|
|
1509
1533
|
level,
|
|
1510
1534
|
}: Readonly<{
|
|
1535
|
+
ariaLabel?: string;
|
|
1536
|
+
columns?: MarketingColumnCount;
|
|
1511
1537
|
items: readonly MarketingRelatedProduct[];
|
|
1512
1538
|
level: MarketingHeadingLevel;
|
|
1513
1539
|
}>) {
|
|
1514
1540
|
return (
|
|
1515
|
-
|
|
1541
|
+
<ul aria-label={ariaLabel} className={marketingColumnClassName("hraness-marketing-related__list", undefined, columns)}>
|
|
1516
1542
|
{items.map((item) => (
|
|
1517
|
-
<
|
|
1518
|
-
{
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
<
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
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>
|
|
1530
1561
|
))}
|
|
1531
|
-
|
|
1562
|
+
</ul>
|
|
1532
1563
|
);
|
|
1533
1564
|
}
|
|
1534
1565
|
|
|
@@ -1536,9 +1567,10 @@ type MarketingRelatedBody =
|
|
|
1536
1567
|
| Readonly<{ groups: readonly MarketingRelatedGroup[]; items?: undefined }>
|
|
1537
1568
|
| Readonly<{ groups?: undefined; items: readonly MarketingRelatedProduct[] }>;
|
|
1538
1569
|
|
|
1539
|
-
/**
|
|
1570
|
+
/** Compact studio product rows, grouped by portfolio category when supplied. */
|
|
1540
1571
|
export function MarketingRelated({
|
|
1541
1572
|
className,
|
|
1573
|
+
columns,
|
|
1542
1574
|
heading,
|
|
1543
1575
|
headingId,
|
|
1544
1576
|
headingLevel = 2,
|
|
@@ -1549,6 +1581,8 @@ export function MarketingRelated({
|
|
|
1549
1581
|
summary,
|
|
1550
1582
|
}: Readonly<{
|
|
1551
1583
|
className?: string;
|
|
1584
|
+
/** Maximum columns for each card row; a group can override it. */
|
|
1585
|
+
columns?: MarketingColumnCount;
|
|
1552
1586
|
heading: string;
|
|
1553
1587
|
headingId: string;
|
|
1554
1588
|
headingLevel?: MarketingHeadingLevel;
|
|
@@ -1557,6 +1591,7 @@ export function MarketingRelated({
|
|
|
1557
1591
|
summary?: string;
|
|
1558
1592
|
}> &
|
|
1559
1593
|
MarketingRelatedBody) {
|
|
1594
|
+
const defaultColumnProps = columns === undefined ? {} : { columns };
|
|
1560
1595
|
return (
|
|
1561
1596
|
<section
|
|
1562
1597
|
aria-labelledby={headingId}
|
|
@@ -1573,30 +1608,33 @@ export function MarketingRelated({
|
|
|
1573
1608
|
summary={summary}
|
|
1574
1609
|
/>
|
|
1575
1610
|
{groups === undefined
|
|
1576
|
-
? (
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
className={classNames("hraness-marketing-related__group-heading")}
|
|
1586
|
-
id={group.headingId}
|
|
1587
|
-
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}
|
|
1588
1620
|
>
|
|
1589
|
-
{
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
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
|
+
))}
|
|
1598
1636
|
</div>
|
|
1599
|
-
)
|
|
1637
|
+
)}
|
|
1600
1638
|
</section>
|
|
1601
1639
|
);
|
|
1602
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
|