@hraness/design-kit 0.32.0 → 0.33.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/dist/stylex.css CHANGED
@@ -2443,6 +2443,14 @@
2443
2443
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
2444
2444
  }
2445
2445
 
2446
+ .x1v4bfo1 {
2447
+ grid-template-columns: repeat(auto-fit,minmax(min(100%,var(--_hraness-marketing-grid-track, 16rem)),1fr));
2448
+ }
2449
+
2450
+ .x1ui45ma {
2451
+ grid-template-columns: repeat(auto-fit,minmax(min(100%,var(--_hraness-marketing-grid-track, 18rem)),1fr));
2452
+ }
2453
+
2446
2454
  .x3g07o8 {
2447
2455
  grid-template-columns: repeat(var(--hraness-marketing-fact-columns, 4),minmax(0,1fr));
2448
2456
  }
@@ -5261,6 +5269,14 @@
5261
5269
  --_hraness-foil-mark-display: none;
5262
5270
  }
5263
5271
 
5272
+ .x9wro72 {
5273
+ --_hraness-marketing-grid-track: max(16rem,calc((100% - (var(--hraness-marketing-grid-columns) - 1) * 1rem) / var(--hraness-marketing-grid-columns)));
5274
+ }
5275
+
5276
+ .xwl1ywu {
5277
+ --_hraness-marketing-grid-track: max(18rem,calc((100% - (var(--hraness-marketing-grid-columns) - 1) * 1rem) / var(--hraness-marketing-grid-columns)));
5278
+ }
5279
+
5264
5280
  .xojny72 {
5265
5281
  --hraness-appearance-accent-foreground: var(--hraness-material-ink, var(--ui-accent-foreground, ButtonText));
5266
5282
  }
@@ -5353,6 +5369,26 @@
5353
5369
  --hraness-marketing-fact-columns: 4;
5354
5370
  }
5355
5371
 
5372
+ .x166dvhg {
5373
+ --hraness-marketing-grid-columns: 1;
5374
+ }
5375
+
5376
+ .x10q4e6v {
5377
+ --hraness-marketing-grid-columns: 2;
5378
+ }
5379
+
5380
+ .xyqi4l0 {
5381
+ --hraness-marketing-grid-columns: 3;
5382
+ }
5383
+
5384
+ .x1g57y38 {
5385
+ --hraness-marketing-grid-columns: 4;
5386
+ }
5387
+
5388
+ .xogmzgw {
5389
+ --hraness-marketing-grid-columns: initial;
5390
+ }
5391
+
5356
5392
  .xphms39 {
5357
5393
  --hraness-marketing-pillar-columns: 1;
5358
5394
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hraness/design-kit",
3
- "version": "0.32.0",
3
+ "version": "0.33.0",
4
4
  "description": "React components and CSS for Hraness apps and product sites: application shells, marketing sections, charts, themes, effects, and syntax highlighting. Built on @hraness/ui.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -6,7 +6,7 @@
6
6
  "name": "@hraness/design-kit",
7
7
  "path": ".",
8
8
  "visibility": "public",
9
- "version": "0.32.0"
9
+ "version": "0.33.0"
10
10
  }
11
11
  ],
12
12
  "contract": "hraness.portfolio-inventory/v1",
@@ -1454,13 +1454,16 @@ html:has(:is(.hraness-marketing-header, .hraness-marketing-header-surface):not([
1454
1454
  }
1455
1455
 
1456
1456
  .hraness-marketing-primitives__list {
1457
+ --hraness-marketing-grid-columns: initial;
1458
+ /* Without an explicit column cap, the track falls back to its natural minimum. */
1459
+ --_hraness-marketing-grid-track: max(18rem, calc((100% - (var(--hraness-marketing-grid-columns) - 1) * 1rem) / var(--hraness-marketing-grid-columns)));
1457
1460
  display: grid;
1458
1461
  align-items: stretch;
1459
1462
  margin: 0;
1460
1463
  padding: 0;
1461
1464
  list-style: none;
1462
1465
  gap: 1rem;
1463
- grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
1466
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--_hraness-marketing-grid-track, 18rem)), 1fr));
1464
1467
  }
1465
1468
 
1466
1469
  .hraness-marketing-primitives__list > * {
@@ -1566,11 +1569,13 @@ html:has(:is(.hraness-marketing-header, .hraness-marketing-header-surface):not([
1566
1569
  * block. The art well clips overflow and contains backgrounds so a logo
1567
1570
  * surface cannot paint through the gutter as one bar. */
1568
1571
  .hraness-marketing-card-row {
1572
+ --hraness-marketing-grid-columns: initial;
1573
+ --_hraness-marketing-grid-track: max(16rem, calc((100% - (var(--hraness-marketing-grid-columns) - 1) * 1rem) / var(--hraness-marketing-grid-columns)));
1569
1574
  display: grid;
1570
1575
  align-items: stretch;
1571
1576
  margin: 0;
1572
1577
  gap: 1rem;
1573
- grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
1578
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--_hraness-marketing-grid-track, 16rem)), 1fr));
1574
1579
  }
1575
1580
 
1576
1581
  .hraness-marketing-card-row > * {
@@ -409,6 +409,7 @@ export function DesignSystemGallery({
409
409
  ]} label="Relay agent commands" />
410
410
  </MarketingSection>
411
411
  <MarketingPrimitives
412
+ columns={3}
412
413
  heading="Three objects cover most work."
413
414
  headingId="design-gallery-primitives-title"
414
415
  headingLevel={3}
@@ -439,7 +440,7 @@ export function DesignSystemGallery({
439
440
  { label: "CLI", summary: "Run a named job.", example: <MarketingCodeBlock code="relay run job-01" /> },
440
441
  { label: "SDK", summary: "Use typed application code." },
441
442
  ]} />
442
- <MarketingCardRow ariaLabel="Release radar" cards={[
443
+ <MarketingCardRow ariaLabel="Release radar" columns={2} cards={[
443
444
  { art: <svg aria-hidden="true" viewBox="0 0 24 24" width="24" height="24"><circle cx="12" cy="12" r="8" /></svg>, href: "#marketing", title: "Grok 4.7", meta: "First observed 21 September 2026." },
444
445
  { art: <svg aria-hidden="true" viewBox="0 0 24 24" width="24" height="24"><rect x="4" y="4" width="16" height="16" rx="4" /></svg>, href: "#gallery-install", title: "GLM 5.3 Flash", meta: "First observed 26 August 2026. Early DeepSWE coverage on OpenRouter." },
445
446
  ]} />
@@ -63,6 +63,10 @@ export const marketingStyles = stylex.create({
63
63
  pillarColumns2: { "--hraness-marketing-pillar-columns": "2" },
64
64
  pillarColumns3: { "--hraness-marketing-pillar-columns": "3" },
65
65
  pillarColumns4: { "--hraness-marketing-pillar-columns": "4" },
66
+ gridColumns1: { "--hraness-marketing-grid-columns": "1" },
67
+ gridColumns2: { "--hraness-marketing-grid-columns": "2" },
68
+ gridColumns3: { "--hraness-marketing-grid-columns": "3" },
69
+ gridColumns4: { "--hraness-marketing-grid-columns": "4" },
66
70
  actionFocus: {
67
71
  outline: { default: null, ":focus-visible": "2px solid var(--hraness-marketing-accent)" },
68
72
  "outline-offset": { default: null, ":focus-visible": "2px" },
@@ -2057,13 +2061,15 @@ export const marketingStyles = stylex.create({
2057
2061
  "font-size": "var(--hraness-paper-section-heading-size, clamp(1.75rem, 3vw, 2.5rem))"
2058
2062
  },
2059
2063
  "primitives__list": {
2064
+ "--hraness-marketing-grid-columns": "initial",
2065
+ "--_hraness-marketing-grid-track": "max(18rem, calc((100% - (var(--hraness-marketing-grid-columns) - 1) * 1rem) / var(--hraness-marketing-grid-columns)))",
2060
2066
  "display": "grid",
2061
2067
  "align-items": "stretch",
2062
2068
  "margin": "0",
2063
2069
  "padding": "0",
2064
2070
  "list-style": "none",
2065
2071
  "gap": "1rem",
2066
- "grid-template-columns": "repeat(auto-fit, minmax(min(100%, 18rem), 1fr))"
2072
+ "grid-template-columns": "repeat(auto-fit, minmax(min(100%, var(--_hraness-marketing-grid-track, 18rem)), 1fr))"
2067
2073
  },
2068
2074
  "primitive": {
2069
2075
  "display": "grid",
@@ -2374,11 +2380,13 @@ export const marketingStyles = stylex.create({
2374
2380
  "line-height": "1.5"
2375
2381
  },
2376
2382
  "card_row": {
2383
+ "--hraness-marketing-grid-columns": "initial",
2384
+ "--_hraness-marketing-grid-track": "max(16rem, calc((100% - (var(--hraness-marketing-grid-columns) - 1) * 1rem) / var(--hraness-marketing-grid-columns)))",
2377
2385
  "display": "grid",
2378
2386
  "align-items": "stretch",
2379
2387
  "margin": "0",
2380
2388
  "gap": "1rem",
2381
- "grid-template-columns": "repeat(auto-fit, minmax(min(100%, 16rem), 1fr))"
2389
+ "grid-template-columns": "repeat(auto-fit, minmax(min(100%, var(--_hraness-marketing-grid-track, 16rem)), 1fr))"
2382
2390
  },
2383
2391
  "card": {
2384
2392
  "display": "flex",
@@ -4441,9 +4449,16 @@ const pillarColumns = {
4441
4449
  4: marketingStyles.pillarColumns4,
4442
4450
  } as const;
4443
4451
 
4452
+ const gridColumns = {
4453
+ 1: marketingStyles.gridColumns1,
4454
+ 2: marketingStyles.gridColumns2,
4455
+ 3: marketingStyles.gridColumns3,
4456
+ 4: marketingStyles.gridColumns4,
4457
+ } as const;
4458
+
4444
4459
  /** Explicit finite columns compose static atoms, including the existing media rules. */
4445
4460
  export function marketingColumnClassName(
4446
- hook: "hraness-marketing-facts" | "hraness-marketing-pillars" | "hraness-marketing-stats__list",
4461
+ hook: "hraness-marketing-facts" | "hraness-marketing-pillars" | "hraness-marketing-stats__list" | "hraness-marketing-card-row" | "hraness-marketing-primitives__list",
4447
4462
  caller: string | undefined,
4448
4463
  columns: MarketingColumnCount | undefined,
4449
4464
  ): string {
@@ -4451,7 +4466,9 @@ export function marketingColumnClassName(
4451
4466
  throw new RangeError("Marketing columns must be 1, 2, 3, or 4 when specified.");
4452
4467
  }
4453
4468
  const columnRecipe = columns === undefined ? undefined
4454
- : (hook === "hraness-marketing-pillars" ? pillarColumns : factColumns)[columns];
4469
+ : (hook === "hraness-marketing-pillars" ? pillarColumns
4470
+ : hook === "hraness-marketing-card-row" || hook === "hraness-marketing-primitives__list" ? gridColumns
4471
+ : factColumns)[columns];
4455
4472
  return [hook, stylex.props(recipes[hook].default, columnRecipe).className, caller]
4456
4473
  .filter((value) => value !== undefined && value.length > 0).join(" ");
4457
4474
  }
@@ -225,16 +225,19 @@ export function MarketingCardRow({
225
225
  cards,
226
226
  children,
227
227
  className,
228
+ columns,
228
229
  }: Readonly<{
229
230
  ariaLabel?: string;
230
231
  cards?: readonly MarketingCardItem[];
231
232
  children?: ReactNode;
232
233
  className?: string;
234
+ /** Maximum columns; cards wrap to fit the available container width. */
235
+ columns?: MarketingColumnCount;
233
236
  }>) {
234
237
  return (
235
238
  <div
236
239
  aria-label={ariaLabel}
237
- className={classNames("hraness-marketing-card-row", className)}
240
+ className={marketingColumnClassName("hraness-marketing-card-row", className, columns)}
238
241
  data-hraness-marketing="card-row"
239
242
  >
240
243
  {cards?.map((card) => (
@@ -1015,6 +1018,7 @@ export interface MarketingPrimitive {
1015
1018
 
1016
1019
  export function MarketingPrimitives({
1017
1020
  className,
1021
+ columns,
1018
1022
  heading,
1019
1023
  headingId,
1020
1024
  headingLevel = 2,
@@ -1024,6 +1028,8 @@ export function MarketingPrimitives({
1024
1028
  summary,
1025
1029
  }: Readonly<{
1026
1030
  className?: string;
1031
+ /** Maximum columns; items wrap to fit the available container width. */
1032
+ columns?: MarketingColumnCount;
1027
1033
  heading: string;
1028
1034
  headingId: string;
1029
1035
  headingLevel?: MarketingHeadingLevel;
@@ -1040,7 +1046,7 @@ export function MarketingPrimitives({
1040
1046
  id={id}
1041
1047
  >
1042
1048
  <MarketingCollectionHeader {...{ heading, headingId, headingLevel, label, summary }} prefix="primitives" />
1043
- <ol className={classNames("hraness-marketing-primitives__list")}>
1049
+ <ol className={marketingColumnClassName("hraness-marketing-primitives__list", undefined, columns)}>
1044
1050
  {items.map((item, index) => (
1045
1051
  <li className={classNames("hraness-marketing-primitive")} key={item.label}>
1046
1052
  <span aria-hidden="true" className={classNames("hraness-marketing-primitive__number")}>