@brunosouzas/design-system 0.5.3 → 0.6.1

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.
@@ -12,14 +12,23 @@ import { tokens } from "../../tokens/generated/tokens.js";
12
12
  import { PIECE_NAMES, PIECES, rings } from "./library.js";
13
13
  import { EIP_ICON_HEIGHT, EIP_ICON_WIDTH, EIP_ICONS } from "./eip-icons.js";
14
14
  import { LINK_ICON_SIZE } from "./link-icons.js";
15
+ import { mira } from "./brand-cast.js";
16
+ import { symbol } from "./symbol.js";
15
17
  import { el, g, r2 } from "./node.js";
16
18
  import { UI_ICON_SIZE } from "./ui-icons.js";
17
19
  import { COLOUR_TOKENS, CURRENT_COLOUR, checkParams, isColourLiteral, MAX_SIZE, PATH_DATA } from "./params.js";
18
20
  export const SAFE_ID = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
19
- const TOP_LEVEL = ["id", "title", "description", "format", "background", "rings", "pieces", "custom", "customAt", "height", "text"];
20
- /** Cover (800x420, the default), banner (1200x420, rounded corners), body diagram (560 laid out, 800 shown) or icon:
21
- * spec cover-cli, "Banner output", "Diagram output", "Icon output". */
22
- export const FORMATS = ["cover", "banner", "diagram", "icon"];
21
+ const TOP_LEVEL = ["id", "title", "description", "format", "background", "rings", "pieces", "custom", "customAt", "height", "text", "signature"];
22
+ /** Cover (800x420, the default), banner (1200x420, rounded corners), body diagram (560 laid out, 800 shown),
23
+ * icon, favicon (the symbol, both themes), linkedin-card (1080x1080) or avatar (500x500, the symbol only):
24
+ * spec cover-cli, "Banner output", "Diagram output", "Icon output", "New icon formats". */
25
+ export const FORMATS = ["cover", "banner", "diagram", "icon", "favicon", "linkedin-card", "og", "avatar"];
26
+ /** Fixed frame sizes of the platform-shaped formats (not style, so not tokens — like EIP_ICON_WIDTH). */
27
+ export const FAVICON_SIZE = 32;
28
+ export const AVATAR_SIZE = 500;
29
+ export const LINKEDIN_CARD_SIZE = 1080;
30
+ export const OG_WIDTH = 1200;
31
+ export const OG_HEIGHT = 630;
23
32
  const CUSTOM_TAGS = ["g", "rect", "circle", "ellipse", "line", "polyline", "polygon", "path", "text"];
24
33
  // Attributes a free-form object may use (design §6): geometry, paint, text and transform.
25
34
  const CUSTOM_ATTRS = new Set([
@@ -323,10 +332,21 @@ const validateResolved = (spec) => {
323
332
  if (spec[key] !== undefined)
324
333
  blocked.push(key);
325
334
  }
335
+ else if (format === "favicon" || format === "avatar") {
336
+ for (const key of ["background", "rings", "custom", "customAt", "height", "signature"]) {
337
+ if (spec[key] !== undefined)
338
+ out.push({ path: key, message: `not used by the ${format} format` });
339
+ }
340
+ for (const key of ["background", "rings", "custom"])
341
+ if (spec[key] !== undefined)
342
+ blocked.push(key);
343
+ }
326
344
  else {
327
345
  if (format === "diagram") {
328
346
  if (spec.background !== undefined)
329
347
  out.push({ path: "background", message: "a diagram is drawn on color.panel; background is for covers and banners" });
348
+ if (spec.signature !== undefined)
349
+ out.push({ path: "signature", message: "not used by the diagram format" });
330
350
  const height = spec.height;
331
351
  if (typeof height !== "number" || !Number.isFinite(height) || height < 1 || height > MAX_SIZE)
332
352
  out.push({ path: "height", message: `expected a number from 1 to ${MAX_SIZE}` });
@@ -337,6 +357,8 @@ const validateResolved = (spec) => {
337
357
  }
338
358
  if (spec.height !== undefined)
339
359
  out.push({ path: "height", message: "only a diagram takes a height" });
360
+ if (spec.signature !== undefined && typeof spec.signature !== "boolean")
361
+ out.push({ path: "signature", message: "expected true or false" });
340
362
  }
341
363
  checkRings(spec, out);
342
364
  if (!isPlainObject(spec.rings) && spec.rings !== undefined)
@@ -364,9 +386,12 @@ const validateResolved = (spec) => {
364
386
  }
365
387
  }
366
388
  if (!Array.isArray(pieces)) {
367
- out.push({ path: "pieces", message: "missing or not an array" });
368
- if (pieces !== undefined)
369
- blocked.push("pieces");
389
+ const piecesOptional = (format === "favicon" || format === "avatar") && pieces === undefined;
390
+ if (!piecesOptional) {
391
+ out.push({ path: "pieces", message: "missing or not an array" });
392
+ if (pieces !== undefined)
393
+ blocked.push("pieces");
394
+ }
370
395
  }
371
396
  else if (format === "icon") {
372
397
  const entry = pieces[0];
@@ -382,6 +407,12 @@ const validateResolved = (spec) => {
382
407
  checkEntry(piece, { ...params, x: 0, y: 0 }, "pieces[0]", out);
383
408
  }
384
409
  }
410
+ else if (format === "favicon" || format === "avatar") {
411
+ if (pieces.length > 0) {
412
+ out.push({ path: "pieces", message: `not used by the ${format} format` });
413
+ blocked.push("pieces");
414
+ }
415
+ }
385
416
  else {
386
417
  for (let index = 0; index < pieces.length; index++) {
387
418
  const entry = pieces[index];
@@ -495,23 +526,62 @@ const diagramTree = (spec) => {
495
526
  const drawnPieces = spec.pieces.map(draw);
496
527
  return root(spec.id, tokens.bodyDiagram.width, r2(height / LAYOUT_SCALE), `0 0 ${width} ${height}`, el("title", { id: `${spec.id}-title` }, spec.title), el("desc", { id: `${spec.id}-desc` }, spec.description), el("defs", {}, el("clipPath", { id: `${spec.id}-frame` }, el("rect", { width, height, rx }))), el("rect", { width, height, rx, fill: tokens.color.panel }), g({ "clip-path": frame }, g({ fill: "none", stroke: tokens.color.ring, "stroke-width": r2(ring.width) }, ...Array.from({ length: ring.count }, (_, i) => el("circle", { cx: spec.rings.cx, cy: spec.rings.cy, r: r2(ring.radius + i * ring.step) })))), g({ "clip-path": frame }, g({ stroke: tokens.color.ink, "stroke-width": tokens.map.outline, "stroke-linejoin": "round" }, ...bodies(spec, drawnPieces)), g({ "font-size": tokens.map.labelSize, "font-weight": tokens.cover.labelWeight, fill: tokens.color.ink, "text-anchor": "middle" }, ...drawnPieces.flatMap((d) => d.text))));
497
528
  };
498
- /** The cover's (banner's, diagram's, icon's) node tree. The spec must be valid for `lang` (validateCoverSpec returned no problem). */
529
+ /** Mira (scale 0.25) and the symbol, bottom-right corner, `cover.signatureMargin` from both edges (spec cover-cli, "Signature lockup"). */
530
+ const signatureGroup = (width, height) => {
531
+ const margin = tokens.cover.signatureMargin;
532
+ const miraScale = 0.25;
533
+ // Mira's own viewBox (sheet7.py's VB): 220 wide, 175 tall, ground at the box's bottom.
534
+ const miraWidth = 220 * miraScale;
535
+ const miraHeight = 175 * miraScale;
536
+ const symbolSize = 24;
537
+ const gap = 6;
538
+ const groupWidth = miraWidth + gap + symbolSize;
539
+ const groupHeight = Math.max(miraHeight, symbolSize);
540
+ const left = width - margin - groupWidth;
541
+ const top = height - margin - groupHeight;
542
+ return g({ "data-piece": "signature" }, ...mira({ x: r2(left + miraWidth / 2), y: r2(top + miraHeight), scale: miraScale }).body, ...symbol({ x: r2(left + miraWidth + gap), y: r2(top + (groupHeight - symbolSize) / 2), scale: symbolSize / 32 }).body);
543
+ };
544
+ /** A favicon (spec cover-cli, "New icon formats"): the symbol, both themes, switched by `prefers-color-scheme`. */
545
+ const faviconTree = (spec) => {
546
+ const size = FAVICON_SIZE;
547
+ return root(spec.id, size, size, `0 0 ${size} ${size}`, el("title", { id: `${spec.id}-title` }, spec.title), el("desc", { id: `${spec.id}-desc` }, spec.description), el("style", {}, `.ds-favicon-dark{display:none}@media (prefers-color-scheme:dark){.ds-favicon-light{display:none}.ds-favicon-dark{display:inline}}`), g({ class: "ds-favicon-light" }, ...symbol({ x: 0, y: 0, surface: "light" }).body), g({ class: "ds-favicon-dark" }, ...symbol({ x: 0, y: 0, surface: "dark" }).body));
548
+ };
549
+ /** An avatar (spec cover-cli, "New icon formats"): the symbol only, filling the frame. */
550
+ const avatarTree = (spec) => {
551
+ const size = AVATAR_SIZE;
552
+ const scale = size / 32;
553
+ return root(spec.id, size, size, `0 0 ${size} ${size}`, el("title", { id: `${spec.id}-title` }, spec.title), el("desc", { id: `${spec.id}-desc` }, spec.description), el("rect", { width: size, height: size, fill: tokens.brand.light.accentText }), g({ transform: `scale(${scale})` }, ...symbol({ x: 0, y: 0, surface: "light" }).body));
554
+ };
555
+ /** The cover's (banner's, diagram's, icon's, favicon's, avatar's) node tree. The spec must be valid for `lang` (validateCoverSpec returned no problem). */
499
556
  export const coverTree = (input, options = {}) => {
500
557
  const spec = forLanguage(input, options.lang);
501
558
  if (spec.format === "icon")
502
559
  return iconTree(spec);
503
560
  if (spec.format === "diagram")
504
561
  return diagramTree(spec);
562
+ if (spec.format === "favicon")
563
+ return faviconTree(spec);
564
+ if (spec.format === "avatar")
565
+ return avatarTree(spec);
505
566
  const banner = spec.format === "banner";
506
- const { width, height } = banner ? tokens.banner : tokens.cover;
507
- // A banner's corners are rounded; a cover keeps today's square frame, attribute for attribute.
567
+ const linkedinCard = spec.format === "linkedin-card";
568
+ const og = spec.format === "og";
569
+ const { width, height } = linkedinCard
570
+ ? { width: LINKEDIN_CARD_SIZE, height: LINKEDIN_CARD_SIZE }
571
+ : og
572
+ ? { width: OG_WIDTH, height: OG_HEIGHT }
573
+ : banner
574
+ ? tokens.banner
575
+ : tokens.cover;
576
+ // A banner's corners are rounded; a cover, a LinkedIn card and an og image keep the square frame, attribute for attribute.
508
577
  const corner = banner ? { rx: tokens.banner.radius } : {};
509
578
  const pair = tokens.coverBackground[spec.background];
510
579
  const drawnPieces = spec.pieces.map(draw);
511
580
  const ringPath = `coverBackground.${spec.background}.ring`;
512
581
  const ringCount = banner ? { count: bannerRingCount(spec.rings.cx, spec.rings.cy, spec.rings.radius) } : {};
513
582
  const frame = `url(#${spec.id}-frame)`;
514
- const outlined = g({ stroke: tokens.color.ink, "stroke-width": tokens.outline.block, "stroke-linejoin": "round" }, ...bodies(spec, drawnPieces));
583
+ const signature = spec.signature ? signatureGroup(width, height) : null;
584
+ const outlined = g({ stroke: tokens.color.ink, "stroke-width": tokens.outline.block, "stroke-linejoin": "round" }, ...bodies(spec, drawnPieces), signature);
515
585
  const labels = g({ "font-size": tokens.cover.labelSize, "font-weight": tokens.cover.labelWeight, fill: tokens.color.ink, "text-anchor": "middle" }, ...drawnPieces.flatMap((d) => d.text));
516
586
  return root(spec.id, width, height, `0 0 ${width} ${height}`, el("title", { id: `${spec.id}-title` }, spec.title), el("desc", { id: `${spec.id}-desc` }, spec.description), el("defs", {}, el("clipPath", { id: `${spec.id}-frame` }, el("rect", { width, height, ...corner }))), el("rect", { width, height, ...corner, fill: pair.fill }), g({ "clip-path": frame }, ...rings({ ...spec.rings, color: ringPath, ...ringCount }).body),
517
587
  // On a banner, pieces and labels are clipped too, so nothing pokes past a rounded corner.
@@ -8,3 +8,8 @@ export { EIP_ICONS, EIP_ICON_NAMES, EIP_ICON_HEIGHT, EIP_ICON_WIDTH, type EipIco
8
8
  export { FORMATS, LANGUAGE, SAFE_ID, backgroundNames, bannerRingCount, comparePaths, coverTree, diagramRings, validateCoverSpec, type CoverFormat, type CoverOptions, type CoverPiece, type CoverRings, type CoverSpec, type CustomNode } from "./cover.ts";
9
9
  export { tokens, type Tokens } from "../../tokens/generated/tokens.ts";
10
10
  export { EMOTE_KINDS, MASCOTS, MASCOT_ACTIONS, MASCOT_FACES, type EmoteKind, type EmoteParams, type MascotAction, type MascotFace, type MascotName, type MascotParams } from "./cast.ts";
11
+ export { CAST_EXPRESSIONS, CAST_VIEWS, type CastExpression, type CastView, type MiraParams, type VisorParams, type DroneParams, type KiuParams, type SinalParams } from "./brand-cast.ts";
12
+ export { BANK_OBJECT_NAMES, type BankObjectName, type BankObjectParams } from "./bank-objects.ts";
13
+ export { type SymbolParams } from "./symbol.ts";
14
+ export { BRAND_NOTATION_ICON_NAMES, type BrandNotationIconName, type BrandNotationIconParams } from "./brand-notation-icons.ts";
15
+ export { CATEGORY_ICON_NAMES, type CategoryIconName, type CategoryIconParams } from "./category-icon.ts";
@@ -13,3 +13,7 @@ export { EIP_ICONS, EIP_ICON_NAMES, EIP_ICON_HEIGHT, EIP_ICON_WIDTH } from "./ei
13
13
  export { FORMATS, LANGUAGE, SAFE_ID, backgroundNames, bannerRingCount, comparePaths, coverTree, diagramRings, validateCoverSpec } from "./cover.js";
14
14
  export { tokens } from "../../tokens/generated/tokens.js";
15
15
  export { EMOTE_KINDS, MASCOTS, MASCOT_ACTIONS, MASCOT_FACES } from "./cast.js";
16
+ export { CAST_EXPRESSIONS, CAST_VIEWS } from "./brand-cast.js";
17
+ export { BANK_OBJECT_NAMES } from "./bank-objects.js";
18
+ export { BRAND_NOTATION_ICON_NAMES } from "./brand-notation-icons.js";
19
+ export { CATEGORY_ICON_NAMES } from "./category-icon.js";
@@ -1,5 +1,11 @@
1
1
  import { emote, mascot } from "./cast.ts";
2
- export { emote, mascot };
2
+ import { mira, visor, drone, kiu, sinal, type MiraParams, type VisorParams, type DroneParams, type KiuParams, type SinalParams } from "./brand-cast.ts";
3
+ import { bankObject, type BankObjectName, type BankObjectParams } from "./bank-objects.ts";
4
+ import { symbol, type SymbolParams } from "./symbol.ts";
5
+ import { brandNotationIcon, type BrandNotationIconName, type BrandNotationIconParams } from "./brand-notation-icons.ts";
6
+ import { categoryIcon, type CategoryIconParams } from "./category-icon.ts";
7
+ export { emote, mascot, mira, visor, drone, kiu, sinal, bankObject, symbol, brandNotationIcon, categoryIcon };
8
+ export type { MiraParams, VisorParams, DroneParams, KiuParams, SinalParams, BankObjectName, BankObjectParams, SymbolParams, BrandNotationIconName, BrandNotationIconParams, CategoryIconParams };
3
9
  export * from "./metro.ts";
4
10
  export * from "./diagram.ts";
5
11
  export * from "./ui-icons.ts";
@@ -332,6 +338,15 @@ export declare const PIECES: {
332
338
  readonly stateStart: import("./piece.ts").Piece<import("./diagram.ts").StateStartParams>;
333
339
  readonly mascot: import("./piece.ts").Piece<import("./cast.ts").MascotParams>;
334
340
  readonly emote: import("./piece.ts").Piece<import("./cast.ts").EmoteParams>;
341
+ readonly mira: import("./piece.ts").Piece<MiraParams>;
342
+ readonly visor: import("./piece.ts").Piece<VisorParams>;
343
+ readonly drone: import("./piece.ts").Piece<DroneParams>;
344
+ readonly kiu: import("./piece.ts").Piece<KiuParams>;
345
+ readonly sinal: import("./piece.ts").Piece<SinalParams>;
346
+ readonly bankObject: import("./piece.ts").Piece<BankObjectParams>;
347
+ readonly symbol: import("./piece.ts").Piece<SymbolParams>;
348
+ readonly brandNotationIcon: import("./piece.ts").Piece<BrandNotationIconParams>;
349
+ readonly categoryIcon: import("./piece.ts").Piece<CategoryIconParams>;
335
350
  };
336
351
  export type PieceName = keyof typeof PIECES;
337
352
  export declare const PIECE_NAMES: PieceName[];
@@ -16,8 +16,13 @@ import { DIAGRAM_PIECES, stateStart } from "./diagram.js";
16
16
  import { uiIcon } from "./ui-icons.js";
17
17
  import { linkIcon } from "./link-icons.js";
18
18
  import { emote, mascot } from "./cast.js";
19
+ import { mira, visor, drone, kiu, sinal } from "./brand-cast.js";
20
+ import { bankObject } from "./bank-objects.js";
21
+ import { symbol } from "./symbol.js";
22
+ import { brandNotationIcon } from "./brand-notation-icons.js";
23
+ import { categoryIcon } from "./category-icon.js";
19
24
  import { codeLength, spans } from "./ink.js";
20
- export { emote, mascot };
25
+ export { emote, mascot, mira, visor, drone, kiu, sinal, bankObject, symbol, brandNotationIcon, categoryIcon };
21
26
  export * from "./metro.js";
22
27
  export * from "./diagram.js";
23
28
  export * from "./ui-icons.js";
@@ -397,5 +402,14 @@ export const PIECES = {
397
402
  stateStart,
398
403
  mascot,
399
404
  emote,
405
+ mira,
406
+ visor,
407
+ drone,
408
+ kiu,
409
+ sinal,
410
+ bankObject,
411
+ symbol,
412
+ brandNotationIcon,
413
+ categoryIcon,
400
414
  };
401
415
  export const PIECE_NAMES = Object.keys(PIECES);
@@ -1,4 +1,4 @@
1
- export declare const SVG_TAGS: readonly ["svg", "g", "title", "desc", "defs", "clipPath", "rect", "circle", "ellipse", "line", "polyline", "polygon", "path", "text", "tspan"];
1
+ export declare const SVG_TAGS: readonly ["svg", "g", "title", "desc", "defs", "clipPath", "style", "rect", "circle", "ellipse", "line", "polyline", "polygon", "path", "text", "tspan"];
2
2
  export type SvgTag = (typeof SVG_TAGS)[number];
3
3
  export type AttrValue = string | number;
4
4
  export type Attrs = Readonly<Record<string, AttrValue>>;
@@ -15,6 +15,7 @@ export const SVG_TAGS = [
15
15
  "desc",
16
16
  "defs",
17
17
  "clipPath",
18
+ "style",
18
19
  "rect",
19
20
  "circle",
20
21
  "ellipse",
@@ -0,0 +1,22 @@
1
+ import { type SurfaceName } from "./ink.ts";
2
+ export type Skin = {
3
+ readonly body: string;
4
+ readonly outline: string;
5
+ readonly visor: string;
6
+ readonly eye: string;
7
+ readonly accent: string;
8
+ };
9
+ /**
10
+ * The cast's resolved colours for one surface. The visor is deliberately not
11
+ * the mirror of the outline: the approved sheets keep the screen face
12
+ * near-black in both themes (contrast against the white body), so dark-theme
13
+ * visor reads `brand.dark.bg`, not the light cream `brand.dark.text`.
14
+ */
15
+ export declare const skin: (surface: SurfaceName) => Skin;
16
+ /** `fill`/`stroke`/`stroke-width`/`stroke-linejoin` for an outlined body shape (the sheets' `ob()`). */
17
+ export declare const outlined: (s: Skin, width?: number) => {
18
+ fill: string;
19
+ stroke: string;
20
+ "stroke-width": number;
21
+ "stroke-linejoin": "round";
22
+ };
@@ -0,0 +1,13 @@
1
+ import { colour } from "./params.js";
2
+ const c = (path) => colour(path);
3
+ /**
4
+ * The cast's resolved colours for one surface. The visor is deliberately not
5
+ * the mirror of the outline: the approved sheets keep the screen face
6
+ * near-black in both themes (contrast against the white body), so dark-theme
7
+ * visor reads `brand.dark.bg`, not the light cream `brand.dark.text`.
8
+ */
9
+ export const skin = (surface) => surface === "light"
10
+ ? { body: c("color.white"), outline: c("brand.light.text"), visor: c("brand.light.text"), eye: c("cast.eyes"), accent: c("brand.light.accent") }
11
+ : { body: c("color.white"), outline: c("brand.dark.textMuted"), visor: c("brand.dark.bg"), eye: c("cast.eyes"), accent: c("brand.dark.accent") };
12
+ /** `fill`/`stroke`/`stroke-width`/`stroke-linejoin` for an outlined body shape (the sheets' `ob()`). */
13
+ export const outlined = (s, width = 8) => ({ fill: s.body, stroke: s.outline, "stroke-width": width, "stroke-linejoin": "round" });
@@ -0,0 +1,9 @@
1
+ import { type SurfaceName } from "./ink.ts";
2
+ export type SymbolParams = {
3
+ x: number;
4
+ y: number;
5
+ surface?: SurfaceName;
6
+ scale?: number;
7
+ };
8
+ /** The brand symbol ("b" with a moon, I5), in a 32×32 box before `scale`. Favicon and avatar are built from this. */
9
+ export declare const symbol: import("./piece.ts").Piece<SymbolParams>;
@@ -0,0 +1,20 @@
1
+ // The brand symbol: the "b" with a moon (identity studio I5): the haste and
2
+ // the ring read as a lowercase b, the moon sits on the accent of the ring.
3
+ // Ported from `~/.hermes/cache/scratch/ab267/board4.py`'s `bmoon()`, the
4
+ // approved source (reused unchanged by every later script, through `final.py`).
5
+ import { drawn, el, g } from "./node.js";
6
+ import { surfaceParam } from "./ink.js";
7
+ import { pos, num } from "./params.js";
8
+ import { definePiece } from "./piece.js";
9
+ import { colour } from "./params.js";
10
+ const c = (path) => colour(path);
11
+ const drawSymbol = (p) => {
12
+ const light = (p.surface ?? "light") === "light";
13
+ const color = light ? c("brand.light.text") : c("brand.dark.text");
14
+ const moon = light ? c("brand.light.accent") : c("brand.dark.accent");
15
+ const scale = p.scale ?? 1; // size is in the 32×32 glyph box, scaled like any other piece
16
+ const body = g({ transform: `translate(${p.x} ${p.y}) scale(${scale})` }, el("rect", { x: 5, y: 3, width: 5.5, height: 26, rx: 2.75, fill: color }), el("circle", { cx: 17.5, cy: 20.5, r: 7.3, fill: "none", stroke: color, "stroke-width": 4.6 }), el("circle", { cx: 27.5, cy: 9, r: 2.8, fill: moon }));
17
+ return drawn([body]);
18
+ };
19
+ /** The brand symbol ("b" with a moon, I5), in a 32×32 box before `scale`. Favicon and avatar are built from this. */
20
+ export const symbol = definePiece("symbol", { x: pos(), y: pos(), surface: surfaceParam, scale: num({ min: 0.1, max: 20 }) }, drawSymbol);
@@ -11,6 +11,42 @@ export declare const tokens: {
11
11
  readonly startRadius: 11;
12
12
  readonly width: 800;
13
13
  };
14
+ readonly brand: {
15
+ readonly dark: {
16
+ readonly accent: "#FF7A45";
17
+ readonly accentText: "#FF7A45";
18
+ readonly bg: "#121110";
19
+ readonly border: "#3B3834";
20
+ readonly borderStrong: "#ADA79D";
21
+ readonly cardBg: "#1D1C1A";
22
+ readonly failure: "#FF6696";
23
+ readonly onAccent: "#121110";
24
+ readonly success: "#5BBF86";
25
+ readonly text: "#F1EEE8";
26
+ readonly textMuted: "#ADA79D";
27
+ readonly trackAi: "#1B1F28";
28
+ readonly trackDelivery: "#18231D";
29
+ readonly trackIntegration: "#2A1C15";
30
+ readonly warning: "#EBB34B";
31
+ };
32
+ readonly light: {
33
+ readonly accent: "#E04E17";
34
+ readonly accentText: "#B83A0C";
35
+ readonly bg: "#F6F3EC";
36
+ readonly border: "#D7D1C5";
37
+ readonly borderStrong: "#5C5852";
38
+ readonly cardBg: "#FFFFFF";
39
+ readonly failure: "#A1124B";
40
+ readonly onAccent: "#FFFFFF";
41
+ readonly success: "#2B7A4B";
42
+ readonly text: "#121212";
43
+ readonly textMuted: "#5C5852";
44
+ readonly trackAi: "#E2E4EC";
45
+ readonly trackDelivery: "#DFE8E1";
46
+ readonly trackIntegration: "#F4E4D8";
47
+ readonly warning: "#8F5F00";
48
+ };
49
+ };
14
50
  readonly cast: {
15
51
  readonly agent: {
16
52
  readonly neck: "#E3E8F5";
@@ -40,6 +76,7 @@ export declare const tokens: {
40
76
  readonly mass: 0.7;
41
77
  readonly stiffness: 170;
42
78
  };
79
+ readonly eyes: "#FFC98A";
43
80
  readonly glow: "#7FD1FF";
44
81
  readonly ground: "#D3DBF5";
45
82
  readonly metal: "#C9D2E8";
@@ -58,6 +95,15 @@ export declare const tokens: {
58
95
  readonly ink: "#0A1033";
59
96
  readonly panel: "#EEF2FF";
60
97
  readonly ring: "#E0E7FB";
98
+ readonly state: {
99
+ readonly backend: "#FF6B6B";
100
+ readonly blocked: "#FF8A3D";
101
+ readonly caller: "#8FB2FF";
102
+ readonly failFast: "#E0661F";
103
+ readonly failure: "#E04848";
104
+ readonly healthy: "#3DDC84";
105
+ readonly transitional: "#FFD25A";
106
+ };
61
107
  readonly transitional: "#FFD25A";
62
108
  readonly white: "#FFFFFF";
63
109
  };
@@ -69,6 +115,7 @@ export declare const tokens: {
69
115
  readonly ringRadius: 90;
70
116
  readonly ringStep: 28;
71
117
  readonly ringWidth: 2;
118
+ readonly signatureMargin: 24;
72
119
  readonly width: 800;
73
120
  };
74
121
  readonly coverBackground: {
@@ -116,6 +163,10 @@ export declare const tokens: {
116
163
  readonly fill: "#14215A";
117
164
  readonly ring: "#1C2D74";
118
165
  };
166
+ readonly neutral: {
167
+ readonly fill: "#F6F3EC";
168
+ readonly ring: "#D8D6D0";
169
+ };
119
170
  readonly olive: {
120
171
  readonly fill: "#8A9A3B";
121
172
  readonly ring: "#7E8E33";
@@ -148,6 +199,18 @@ export declare const tokens: {
148
199
  readonly fill: "#1F8A8A";
149
200
  readonly ring: "#2A9A99";
150
201
  };
202
+ readonly trackAi: {
203
+ readonly fill: "#E2E4EC";
204
+ readonly ring: "#C7C9D0";
205
+ };
206
+ readonly trackDelivery: {
207
+ readonly fill: "#DFE8E1";
208
+ readonly ring: "#C4CCC6";
209
+ };
210
+ readonly trackIntegration: {
211
+ readonly fill: "#F4E4D8";
212
+ readonly ring: "#D7C9BE";
213
+ };
151
214
  readonly violet: {
152
215
  readonly fill: "#5B3CC4";
153
216
  readonly ring: "#6748CF";
@@ -12,6 +12,42 @@ export const tokens = {
12
12
  "startRadius": 11,
13
13
  "width": 800
14
14
  },
15
+ "brand": {
16
+ "dark": {
17
+ "accent": "#FF7A45",
18
+ "accentText": "#FF7A45",
19
+ "bg": "#121110",
20
+ "border": "#3B3834",
21
+ "borderStrong": "#ADA79D",
22
+ "cardBg": "#1D1C1A",
23
+ "failure": "#FF6696",
24
+ "onAccent": "#121110",
25
+ "success": "#5BBF86",
26
+ "text": "#F1EEE8",
27
+ "textMuted": "#ADA79D",
28
+ "trackAi": "#1B1F28",
29
+ "trackDelivery": "#18231D",
30
+ "trackIntegration": "#2A1C15",
31
+ "warning": "#EBB34B"
32
+ },
33
+ "light": {
34
+ "accent": "#E04E17",
35
+ "accentText": "#B83A0C",
36
+ "bg": "#F6F3EC",
37
+ "border": "#D7D1C5",
38
+ "borderStrong": "#5C5852",
39
+ "cardBg": "#FFFFFF",
40
+ "failure": "#A1124B",
41
+ "onAccent": "#FFFFFF",
42
+ "success": "#2B7A4B",
43
+ "text": "#121212",
44
+ "textMuted": "#5C5852",
45
+ "trackAi": "#E2E4EC",
46
+ "trackDelivery": "#DFE8E1",
47
+ "trackIntegration": "#F4E4D8",
48
+ "warning": "#8F5F00"
49
+ }
50
+ },
15
51
  "cast": {
16
52
  "agent": {
17
53
  "neck": "#E3E8F5",
@@ -41,6 +77,7 @@ export const tokens = {
41
77
  "mass": 0.7,
42
78
  "stiffness": 170
43
79
  },
80
+ "eyes": "#FFC98A",
44
81
  "glow": "#7FD1FF",
45
82
  "ground": "#D3DBF5",
46
83
  "metal": "#C9D2E8",
@@ -59,6 +96,15 @@ export const tokens = {
59
96
  "ink": "#0A1033",
60
97
  "panel": "#EEF2FF",
61
98
  "ring": "#E0E7FB",
99
+ "state": {
100
+ "backend": "#FF6B6B",
101
+ "blocked": "#FF8A3D",
102
+ "caller": "#8FB2FF",
103
+ "failFast": "#E0661F",
104
+ "failure": "#E04848",
105
+ "healthy": "#3DDC84",
106
+ "transitional": "#FFD25A"
107
+ },
62
108
  "transitional": "#FFD25A",
63
109
  "white": "#FFFFFF"
64
110
  },
@@ -70,6 +116,7 @@ export const tokens = {
70
116
  "ringRadius": 90,
71
117
  "ringStep": 28,
72
118
  "ringWidth": 2,
119
+ "signatureMargin": 24,
73
120
  "width": 800
74
121
  },
75
122
  "coverBackground": {
@@ -117,6 +164,10 @@ export const tokens = {
117
164
  "fill": "#14215A",
118
165
  "ring": "#1C2D74"
119
166
  },
167
+ "neutral": {
168
+ "fill": "#F6F3EC",
169
+ "ring": "#D8D6D0"
170
+ },
120
171
  "olive": {
121
172
  "fill": "#8A9A3B",
122
173
  "ring": "#7E8E33"
@@ -149,6 +200,18 @@ export const tokens = {
149
200
  "fill": "#1F8A8A",
150
201
  "ring": "#2A9A99"
151
202
  },
203
+ "trackAi": {
204
+ "fill": "#E2E4EC",
205
+ "ring": "#C7C9D0"
206
+ },
207
+ "trackDelivery": {
208
+ "fill": "#DFE8E1",
209
+ "ring": "#C4CCC6"
210
+ },
211
+ "trackIntegration": {
212
+ "fill": "#F4E4D8",
213
+ "ring": "#D7C9BE"
214
+ },
152
215
  "violet": {
153
216
  "fill": "#5B3CC4",
154
217
  "ring": "#6748CF"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brunosouzas/design-system",
3
- "version": "0.5.3",
3
+ "version": "0.6.1",
4
4
  "description": "Design tokens and illustration pieces of brunosouzas.com: tokens as CSS, JSON and TypeScript, pieces that draw SVG (and React), and a cover command.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -8,6 +8,36 @@
8
8
  --ds-body-diagram-ring-radius: 70px;
9
9
  --ds-body-diagram-start-radius: 11px;
10
10
  --ds-body-diagram-width: 800px;
11
+ --ds-brand-dark-accent: #FF7A45;
12
+ --ds-brand-dark-accent-text: #FF7A45;
13
+ --ds-brand-dark-bg: #121110;
14
+ --ds-brand-dark-border: #3B3834;
15
+ --ds-brand-dark-border-strong: #ADA79D;
16
+ --ds-brand-dark-card-bg: #1D1C1A;
17
+ --ds-brand-dark-failure: #FF6696;
18
+ --ds-brand-dark-on-accent: #121110;
19
+ --ds-brand-dark-success: #5BBF86;
20
+ --ds-brand-dark-text: #F1EEE8;
21
+ --ds-brand-dark-text-muted: #ADA79D;
22
+ --ds-brand-dark-track-ai: #1B1F28;
23
+ --ds-brand-dark-track-delivery: #18231D;
24
+ --ds-brand-dark-track-integration: #2A1C15;
25
+ --ds-brand-dark-warning: #EBB34B;
26
+ --ds-brand-light-accent: #E04E17;
27
+ --ds-brand-light-accent-text: #B83A0C;
28
+ --ds-brand-light-bg: #F6F3EC;
29
+ --ds-brand-light-border: #D7D1C5;
30
+ --ds-brand-light-border-strong: #5C5852;
31
+ --ds-brand-light-card-bg: #FFFFFF;
32
+ --ds-brand-light-failure: #A1124B;
33
+ --ds-brand-light-on-accent: #FFFFFF;
34
+ --ds-brand-light-success: #2B7A4B;
35
+ --ds-brand-light-text: #121212;
36
+ --ds-brand-light-text-muted: #5C5852;
37
+ --ds-brand-light-track-ai: #E2E4EC;
38
+ --ds-brand-light-track-delivery: #DFE8E1;
39
+ --ds-brand-light-track-integration: #F4E4D8;
40
+ --ds-brand-light-warning: #8F5F00;
11
41
  --ds-cast-agent-neck: #E3E8F5;
12
42
  --ds-cast-agent-shine: #E6ECFF;
13
43
  --ds-cast-architect-fill: #22B5A4;
@@ -24,6 +54,7 @@
24
54
  --ds-cast-emote-pop-damping: 9;
25
55
  --ds-cast-emote-pop-mass: 0.7;
26
56
  --ds-cast-emote-pop-stiffness: 170;
57
+ --ds-cast-eyes: #FFC98A;
27
58
  --ds-cast-glow: #7FD1FF;
28
59
  --ds-cast-ground: #D3DBF5;
29
60
  --ds-cast-metal: #C9D2E8;
@@ -38,6 +69,13 @@
38
69
  --ds-color-ink: #0A1033;
39
70
  --ds-color-panel: #EEF2FF;
40
71
  --ds-color-ring: #E0E7FB;
72
+ --ds-color-state-backend: #FF6B6B;
73
+ --ds-color-state-blocked: #FF8A3D;
74
+ --ds-color-state-caller: #8FB2FF;
75
+ --ds-color-state-fail-fast: #E0661F;
76
+ --ds-color-state-failure: #E04848;
77
+ --ds-color-state-healthy: #3DDC84;
78
+ --ds-color-state-transitional: #FFD25A;
41
79
  --ds-color-transitional: #FFD25A;
42
80
  --ds-color-white: #FFFFFF;
43
81
  --ds-cover-height: 420px;
@@ -47,6 +85,7 @@
47
85
  --ds-cover-ring-radius: 90px;
48
86
  --ds-cover-ring-step: 28px;
49
87
  --ds-cover-ring-width: 2px;
88
+ --ds-cover-signature-margin: 24px;
50
89
  --ds-cover-width: 800px;
51
90
  --ds-cover-background-blush-fill: #F6CFE0;
52
91
  --ds-cover-background-blush-ring: #ECBAD0;
@@ -70,6 +109,8 @@
70
109
  --ds-cover-background-mustard-ring: #E6B33E;
71
110
  --ds-cover-background-navy-fill: #14215A;
72
111
  --ds-cover-background-navy-ring: #1C2D74;
112
+ --ds-cover-background-neutral-fill: #F6F3EC;
113
+ --ds-cover-background-neutral-ring: #D8D6D0;
73
114
  --ds-cover-background-olive-fill: #8A9A3B;
74
115
  --ds-cover-background-olive-ring: #7E8E33;
75
116
  --ds-cover-background-peach-fill: #F4D8BC;
@@ -86,6 +127,12 @@
86
127
  --ds-cover-background-slate-ring: #38466A;
87
128
  --ds-cover-background-teal-fill: #1F8A8A;
88
129
  --ds-cover-background-teal-ring: #2A9A99;
130
+ --ds-cover-background-track-ai-fill: #E2E4EC;
131
+ --ds-cover-background-track-ai-ring: #C7C9D0;
132
+ --ds-cover-background-track-delivery-fill: #DFE8E1;
133
+ --ds-cover-background-track-delivery-ring: #C4CCC6;
134
+ --ds-cover-background-track-integration-fill: #F4E4D8;
135
+ --ds-cover-background-track-integration-ring: #D7C9BE;
89
136
  --ds-cover-background-violet-fill: #5B3CC4;
90
137
  --ds-cover-background-violet-ring: #6748CF;
91
138
  --ds-cover-background-wine-fill: #6B2340;