@praecipio/brand 0.1.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.
@@ -0,0 +1,150 @@
1
+ type Tier = 'prime' | 'accent' | 'neutral';
2
+ interface Rgb {
3
+ r: number;
4
+ g: number;
5
+ b: number;
6
+ }
7
+ interface BrandColor {
8
+ name: string;
9
+ tier: Tier;
10
+ hex: string;
11
+ rgb: Rgb;
12
+ /**
13
+ * CMYK percentages exactly as published in guide v2.01 / Color-Values PDF.
14
+ * ⚠ Print intent is UNSPECIFIED — the guide names no process, ink standard
15
+ * (SWOP/GRACoL/FOGRA), ICC profile, or substrate. Treat as reference
16
+ * numbers, not press-ready separations; see CMYK_INTENT.
17
+ */
18
+ cmyk: [number, number, number, number];
19
+ pantone: string;
20
+ }
21
+ /** Provenance caveat for all CMYK values in this palette. */
22
+ declare const CMYK_INTENT = "as published (guide v2.01, 2024) \u2014 process/ICC/substrate unspecified; needs a print-spec ruling";
23
+ declare const prime: {
24
+ readonly orange: BrandColor;
25
+ readonly teal: BrandColor;
26
+ readonly maroon: BrandColor;
27
+ readonly navy: BrandColor;
28
+ };
29
+ declare const accent: {
30
+ readonly peach: BrandColor;
31
+ readonly mint: BrandColor;
32
+ readonly lavender: BrandColor;
33
+ readonly cyan: BrandColor;
34
+ readonly coral: BrandColor;
35
+ readonly steel: BrandColor;
36
+ readonly mauve: BrandColor;
37
+ readonly slate: BrandColor;
38
+ };
39
+ declare const neutral: {
40
+ readonly black: BrandColor;
41
+ readonly ink: BrandColor;
42
+ readonly 'gray-dark': BrandColor;
43
+ readonly gray: BrandColor;
44
+ readonly 'gray-light': BrandColor;
45
+ readonly 'gray-faint': BrandColor;
46
+ };
47
+ declare const palette: readonly BrandColor[];
48
+ declare function hexToRgb(hex: string): Rgb;
49
+ declare function rgbToHex({ r, g, b }: Rgb): string;
50
+ /**
51
+ * Tint/shade ladder — guide p.20. Tints mix toward white at 10/20/30/40%
52
+ * uniformly. Shade factors were hand-tuned per color (already-dark primes get
53
+ * gentler steps), so they are data, not a formula. From the canonical hexes
54
+ * this reproduces the guide's printed values exactly. (The historical .ase
55
+ * ladder was computed from off-by-one base values — a drift this retires.)
56
+ * Guide rule: marketing collateral always uses the primary colors; tints and
57
+ * shades exist for depth via blending/opacity in digital work only.
58
+ */
59
+ interface Ladder {
60
+ base: string;
61
+ tints: string[];
62
+ shades: string[];
63
+ }
64
+ declare const TINT_STEPS: readonly [0.1, 0.2, 0.3, 0.4];
65
+ declare const shadeFactors: Record<keyof typeof prime, readonly number[]>;
66
+ declare function ladder(hex: string, shades?: readonly number[]): Ladder;
67
+ /** The four published prime ladders, exactly as printed in the guide. */
68
+ declare function primeLadder(name: keyof typeof prime): Ladder;
69
+
70
+ /** Guide p.13: minimum logo width is 0.8 in / 2.032 cm / 80 px. */
71
+ declare const MIN_LOGO_WIDTH_PX = 80;
72
+ /** Guide p.19: primary colors should comprise at least 60% of a graphic. */
73
+ declare const MIN_PRIMARY_COVERAGE = 0.6;
74
+ /** WCAG 2.x relative luminance. */
75
+ declare function luminance(color: string | Rgb): number;
76
+ /** WCAG contrast ratio between two colors, >= 1. */
77
+ declare function contrast(a: string, b: string): number;
78
+ /**
79
+ * Guide p.19: "Accent colors should never be used on text against a white
80
+ * background." White text on an accent background is allowed only for
81
+ * heavy/bold fonts. This predicate encodes the first (hard) rule.
82
+ */
83
+ declare function isAllowedTextOnWhite(hex: string): boolean;
84
+ /** Guide p.19: "Do not create gradients with these colors." */
85
+ declare const GRADIENTS_ALLOWED = false;
86
+ /** Guide p.24: pattern overlays behind text cap at 15% opacity (multiply). */
87
+ declare const MAX_PATTERN_OPACITY = 0.15;
88
+
89
+ interface FontRole {
90
+ family: string;
91
+ fallback: string;
92
+ role: 'heading' | 'body';
93
+ /** Licensing note — governs where the files may ship. */
94
+ license: string;
95
+ }
96
+ declare const fonts: {
97
+ readonly heading: {
98
+ readonly family: "Freight Sans Pro";
99
+ readonly fallback: "'Nunito Sans', system-ui, sans-serif";
100
+ readonly role: "heading";
101
+ readonly license: "commercial (Adobe Fonts / GarageFonts) — private use only";
102
+ };
103
+ readonly body: {
104
+ readonly family: "Nunito Sans";
105
+ readonly fallback: "system-ui, sans-serif";
106
+ readonly role: "body";
107
+ readonly license: "OFL 1.1";
108
+ };
109
+ };
110
+ declare const fontStack: (role: keyof typeof fonts) => string;
111
+ /** Published specimen specs: weight and size/leading per role. */
112
+ declare const typeSpecs: {
113
+ readonly heading: readonly ["Black 11/14", "Bold 11/14", "Semibold 11/14"];
114
+ readonly body: readonly ["Bold 10/14", "Regular 10/14", "Italic 10/14"];
115
+ };
116
+
117
+ declare const orientations: {
118
+ readonly hori: "Horizontal — the primary orientation; use when in doubt";
119
+ readonly verti: "Vertical (stacked) — avoid at small sizes; can become illegible";
120
+ readonly 'verti-sm': "Vertical small — stacked variant tuned for smaller sizes";
121
+ readonly logomark: "Logomark — the P icon; supportive, used alongside the full logo";
122
+ };
123
+ type VisualClass = 'primary' | 'reverse' | 'black' | 'white';
124
+ interface Colorway {
125
+ /** Which visually-distinct treatment this colorway renders as. */
126
+ visual: VisualClass;
127
+ use: string;
128
+ }
129
+ declare const colorways: Record<string, Colorway>;
130
+ /** Canonical colorway to display for each visually-distinct treatment. */
131
+ declare const canonicalColorway: Record<VisualClass, string>;
132
+ /** Unacceptable usage — the complete list. */
133
+ declare const logoDoNots: readonly ["Do not use a one-color overlay on digital assets", "Do not use unapproved color combinations", "Do not add a drop shadow", "Do not warp or skew the logo", "Do not overlay the logo on complicated or busy backgrounds", "Do not crop the logo", "Do not outline the logo", "Do not change the color of the line 'P' inside the logomark", "Do not rotate or set the logo at an angle", "Do not overlay complicated effects, like bevel or emboss, to a logo", "Do not change the opacity of the logo", "Do not recreate using any other typefaces", "Do not change the integrity of the logo"];
134
+ declare const logomarkUsage: string;
135
+ /** Clear space: keep the logomark-height padding free around the logo. */
136
+ declare const clearspace = "logomark height on all sides";
137
+
138
+ declare const iconRecipe: {
139
+ readonly library: "Google Material Symbols";
140
+ readonly style: "Rounded";
141
+ readonly fill: 0;
142
+ readonly weight: 400;
143
+ readonly grade: 0;
144
+ readonly opticalSize: 40;
145
+ readonly lineColors: readonly ["black", "white"];
146
+ readonly chipColors: "any prime or accent color from the palette";
147
+ };
148
+ declare const iconUsage: string;
149
+
150
+ export { type BrandColor, CMYK_INTENT, type Colorway, type FontRole, GRADIENTS_ALLOWED, type Ladder, MAX_PATTERN_OPACITY, MIN_LOGO_WIDTH_PX, MIN_PRIMARY_COVERAGE, type Rgb, TINT_STEPS, type Tier, type VisualClass, accent, canonicalColorway, clearspace, colorways, contrast, fontStack, fonts, hexToRgb, iconRecipe, iconUsage, isAllowedTextOnWhite, ladder, logoDoNots, logomarkUsage, luminance, neutral, orientations, palette, prime, primeLadder, rgbToHex, shadeFactors, typeSpecs };
package/dist/index.js ADDED
@@ -0,0 +1,63 @@
1
+ import {
2
+ CMYK_INTENT,
3
+ GRADIENTS_ALLOWED,
4
+ MAX_PATTERN_OPACITY,
5
+ MIN_LOGO_WIDTH_PX,
6
+ MIN_PRIMARY_COVERAGE,
7
+ TINT_STEPS,
8
+ accent,
9
+ canonicalColorway,
10
+ clearspace,
11
+ colorways,
12
+ contrast,
13
+ fontStack,
14
+ fonts,
15
+ hexToRgb,
16
+ iconRecipe,
17
+ iconUsage,
18
+ isAllowedTextOnWhite,
19
+ ladder,
20
+ logoDoNots,
21
+ logomarkUsage,
22
+ luminance,
23
+ neutral,
24
+ orientations,
25
+ palette,
26
+ prime,
27
+ primeLadder,
28
+ rgbToHex,
29
+ shadeFactors,
30
+ typeSpecs
31
+ } from "./chunk-A6WMWOXD.js";
32
+ export {
33
+ CMYK_INTENT,
34
+ GRADIENTS_ALLOWED,
35
+ MAX_PATTERN_OPACITY,
36
+ MIN_LOGO_WIDTH_PX,
37
+ MIN_PRIMARY_COVERAGE,
38
+ TINT_STEPS,
39
+ accent,
40
+ canonicalColorway,
41
+ clearspace,
42
+ colorways,
43
+ contrast,
44
+ fontStack,
45
+ fonts,
46
+ hexToRgb,
47
+ iconRecipe,
48
+ iconUsage,
49
+ isAllowedTextOnWhite,
50
+ ladder,
51
+ logoDoNots,
52
+ logomarkUsage,
53
+ luminance,
54
+ neutral,
55
+ orientations,
56
+ palette,
57
+ prime,
58
+ primeLadder,
59
+ rgbToHex,
60
+ shadeFactors,
61
+ typeSpecs
62
+ };
63
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,118 @@
1
+ /* praecipio-mkdocs.css — generated by @praecipio/brand; do not edit.
2
+ * Brands any mkdocs-material site:
3
+ * theme: { name: material, palette: { primary: custom } }
4
+ * extra_css: [praecipio-mkdocs.css]
5
+ */
6
+ :root {
7
+ --praecipio-prime-orange: #c84f09;
8
+ --praecipio-prime-teal: #054950;
9
+ --praecipio-prime-maroon: #6a1933;
10
+ --praecipio-prime-navy: #2b3f60;
11
+ --praecipio-accent-peach: #ffbe7a;
12
+ --praecipio-accent-mint: #92e5b7;
13
+ --praecipio-accent-lavender: #b699e1;
14
+ --praecipio-accent-cyan: #39d3d3;
15
+ --praecipio-accent-coral: #dd7b6c;
16
+ --praecipio-accent-steel: #6eabb3;
17
+ --praecipio-accent-mauve: #a4809c;
18
+ --praecipio-accent-slate: #4f8299;
19
+ --praecipio-neutral-black: #000000;
20
+ --praecipio-neutral-ink: #332e27;
21
+ --praecipio-neutral-gray-dark: #7a6e67;
22
+ --praecipio-neutral-gray: #9e968d;
23
+ --praecipio-neutral-gray-light: #c5b9ac;
24
+ --praecipio-neutral-gray-faint: #d6d1ca;
25
+ --praecipio-orange-tint-10: #ce6122;
26
+ --praecipio-orange-tint-20: #d3723a;
27
+ --praecipio-orange-tint-30: #d98453;
28
+ --praecipio-orange-tint-40: #de956b;
29
+ --praecipio-orange-shade-80: #a03f07;
30
+ --praecipio-orange-shade-60: #782f05;
31
+ --praecipio-orange-shade-40: #502004;
32
+ --praecipio-orange-shade-20: #281002;
33
+ --praecipio-teal-tint-10: #1e5b62;
34
+ --praecipio-teal-tint-20: #376d73;
35
+ --praecipio-teal-tint-30: #508085;
36
+ --praecipio-teal-tint-40: #699296;
37
+ --praecipio-teal-shade-90: #054248;
38
+ --praecipio-teal-shade-80: #043a40;
39
+ --praecipio-teal-shade-70: #043338;
40
+ --praecipio-teal-shade-50: #032528;
41
+ --praecipio-maroon-tint-10: #793047;
42
+ --praecipio-maroon-tint-20: #88475c;
43
+ --praecipio-maroon-tint-30: #975e70;
44
+ --praecipio-maroon-tint-40: #a67585;
45
+ --praecipio-maroon-shade-90: #5f172e;
46
+ --praecipio-maroon-shade-80: #551429;
47
+ --praecipio-maroon-shade-70: #4a1224;
48
+ --praecipio-maroon-shade-60: #400f1f;
49
+ --praecipio-navy-tint-10: #405270;
50
+ --praecipio-navy-tint-20: #556580;
51
+ --praecipio-navy-tint-30: #6b7990;
52
+ --praecipio-navy-tint-40: #808ca0;
53
+ --praecipio-navy-shade-90: #273956;
54
+ --praecipio-navy-shade-80: #22324d;
55
+ --praecipio-navy-shade-70: #1e2c43;
56
+ --praecipio-navy-shade-60: #1a263a;
57
+ --praecipio-font-heading: 'Freight Sans Pro', 'Nunito Sans', system-ui, sans-serif;
58
+ --praecipio-font-body: 'Nunito Sans', system-ui, sans-serif;
59
+ }
60
+
61
+ /* mkdocs-material variable mapping — three schemes:
62
+ * default = light on warm design-gray paper (never stark white)
63
+ * twilight = dim warm neutral, graphic-arts gray for judging color
64
+ * slate = dark
65
+ * Surfaces for artwork tiles are exposed as --praecipio-tile-* so galleries
66
+ * read correctly in every scheme. */
67
+ :root, [data-md-color-scheme="default"] {
68
+ --md-primary-fg-color: var(--praecipio-prime-teal);
69
+ --md-primary-fg-color--light: var(--praecipio-teal-tint-20);
70
+ --md-primary-fg-color--dark: var(--praecipio-teal-shade-80);
71
+ --md-accent-fg-color: var(--praecipio-prime-orange);
72
+ --md-typeset-a-color: var(--praecipio-prime-teal);
73
+ --md-text-font-family: var(--praecipio-font-body);
74
+ --md-default-bg-color: #f6f4f1; /* warm paper — not white */
75
+ --md-code-bg-color: #edeae5;
76
+ --praecipio-tile-a: #ece9e4;
77
+ --praecipio-tile-b: #f8f6f3;
78
+ --praecipio-card-bg: #fffefc;
79
+ --praecipio-card-fg: var(--praecipio-neutral-ink);
80
+ }
81
+ [data-md-color-scheme="twilight"] {
82
+ --md-default-bg-color: #33302b; /* warm neutral gray — design viewing */
83
+ --md-default-fg-color: rgba(232, 228, 222, 0.87);
84
+ --md-default-fg-color--light: rgba(232, 228, 222, 0.62);
85
+ --md-default-fg-color--lighter: rgba(232, 228, 222, 0.32);
86
+ --md-default-fg-color--lightest: rgba(232, 228, 222, 0.12);
87
+ --md-typeset-color: rgba(232, 228, 222, 0.87);
88
+ --md-typeset-a-color: var(--praecipio-teal-tint-40);
89
+ --md-accent-fg-color: var(--praecipio-orange-tint-30);
90
+ --md-primary-fg-color: var(--praecipio-teal-shade-80);
91
+ --md-code-bg-color: #2a2723;
92
+ --md-code-fg-color: var(--praecipio-neutral-gray-light);
93
+ --md-footer-bg-color: #2a2723;
94
+ --praecipio-tile-a: #4a463f;
95
+ --praecipio-tile-b: #55504a;
96
+ --praecipio-card-bg: #3d3934;
97
+ --praecipio-card-fg: var(--praecipio-neutral-gray-light);
98
+ }
99
+ [data-md-color-scheme="slate"] {
100
+ --md-primary-fg-color: var(--praecipio-prime-teal);
101
+ --md-accent-fg-color: var(--praecipio-prime-orange);
102
+ --md-typeset-a-color: var(--praecipio-teal-tint-40);
103
+ --md-default-bg-color: #1b1916; /* warm near-black, not blue-slate */
104
+ --praecipio-tile-a: #35322d;
105
+ --praecipio-tile-b: #403c36;
106
+ --praecipio-card-bg: #262320;
107
+ --praecipio-card-fg: var(--praecipio-neutral-gray-light);
108
+ }
109
+ .md-typeset h1, .md-typeset h2, .md-typeset h3,
110
+ .md-typeset h4, .md-typeset h5, .md-typeset h6 {
111
+ font-family: var(--praecipio-font-heading);
112
+ }
113
+ /* restrained brand pop: accent rule under page titles */
114
+ .md-typeset h1 {
115
+ padding-bottom: 0.25em;
116
+ border-bottom: 3px solid var(--praecipio-prime-orange);
117
+ display: inline-block;
118
+ }
@@ -0,0 +1,55 @@
1
+ /* Praecipio brand tokens — generated by @praecipio/brand; do not edit. */
2
+ :root {
3
+ --praecipio-prime-orange: #c84f09;
4
+ --praecipio-prime-teal: #054950;
5
+ --praecipio-prime-maroon: #6a1933;
6
+ --praecipio-prime-navy: #2b3f60;
7
+ --praecipio-accent-peach: #ffbe7a;
8
+ --praecipio-accent-mint: #92e5b7;
9
+ --praecipio-accent-lavender: #b699e1;
10
+ --praecipio-accent-cyan: #39d3d3;
11
+ --praecipio-accent-coral: #dd7b6c;
12
+ --praecipio-accent-steel: #6eabb3;
13
+ --praecipio-accent-mauve: #a4809c;
14
+ --praecipio-accent-slate: #4f8299;
15
+ --praecipio-neutral-black: #000000;
16
+ --praecipio-neutral-ink: #332e27;
17
+ --praecipio-neutral-gray-dark: #7a6e67;
18
+ --praecipio-neutral-gray: #9e968d;
19
+ --praecipio-neutral-gray-light: #c5b9ac;
20
+ --praecipio-neutral-gray-faint: #d6d1ca;
21
+ --praecipio-orange-tint-10: #ce6122;
22
+ --praecipio-orange-tint-20: #d3723a;
23
+ --praecipio-orange-tint-30: #d98453;
24
+ --praecipio-orange-tint-40: #de956b;
25
+ --praecipio-orange-shade-80: #a03f07;
26
+ --praecipio-orange-shade-60: #782f05;
27
+ --praecipio-orange-shade-40: #502004;
28
+ --praecipio-orange-shade-20: #281002;
29
+ --praecipio-teal-tint-10: #1e5b62;
30
+ --praecipio-teal-tint-20: #376d73;
31
+ --praecipio-teal-tint-30: #508085;
32
+ --praecipio-teal-tint-40: #699296;
33
+ --praecipio-teal-shade-90: #054248;
34
+ --praecipio-teal-shade-80: #043a40;
35
+ --praecipio-teal-shade-70: #043338;
36
+ --praecipio-teal-shade-50: #032528;
37
+ --praecipio-maroon-tint-10: #793047;
38
+ --praecipio-maroon-tint-20: #88475c;
39
+ --praecipio-maroon-tint-30: #975e70;
40
+ --praecipio-maroon-tint-40: #a67585;
41
+ --praecipio-maroon-shade-90: #5f172e;
42
+ --praecipio-maroon-shade-80: #551429;
43
+ --praecipio-maroon-shade-70: #4a1224;
44
+ --praecipio-maroon-shade-60: #400f1f;
45
+ --praecipio-navy-tint-10: #405270;
46
+ --praecipio-navy-tint-20: #556580;
47
+ --praecipio-navy-tint-30: #6b7990;
48
+ --praecipio-navy-tint-40: #808ca0;
49
+ --praecipio-navy-shade-90: #273956;
50
+ --praecipio-navy-shade-80: #22324d;
51
+ --praecipio-navy-shade-70: #1e2c43;
52
+ --praecipio-navy-shade-60: #1a263a;
53
+ --praecipio-font-heading: 'Freight Sans Pro', 'Nunito Sans', system-ui, sans-serif;
54
+ --praecipio-font-body: 'Nunito Sans', system-ui, sans-serif;
55
+ }
@@ -0,0 +1,74 @@
1
+ {
2
+ "orange": {
3
+ "hex": "#C84F09",
4
+ "tier": "prime"
5
+ },
6
+ "teal": {
7
+ "hex": "#054950",
8
+ "tier": "prime"
9
+ },
10
+ "maroon": {
11
+ "hex": "#6A1933",
12
+ "tier": "prime"
13
+ },
14
+ "navy": {
15
+ "hex": "#2B3F60",
16
+ "tier": "prime"
17
+ },
18
+ "peach": {
19
+ "hex": "#FFBE7A",
20
+ "tier": "accent"
21
+ },
22
+ "mint": {
23
+ "hex": "#92E5B7",
24
+ "tier": "accent"
25
+ },
26
+ "lavender": {
27
+ "hex": "#B699E1",
28
+ "tier": "accent"
29
+ },
30
+ "cyan": {
31
+ "hex": "#39D3D3",
32
+ "tier": "accent"
33
+ },
34
+ "coral": {
35
+ "hex": "#DD7B6C",
36
+ "tier": "accent"
37
+ },
38
+ "steel": {
39
+ "hex": "#6EABB3",
40
+ "tier": "accent"
41
+ },
42
+ "mauve": {
43
+ "hex": "#A4809C",
44
+ "tier": "accent"
45
+ },
46
+ "slate": {
47
+ "hex": "#4F8299",
48
+ "tier": "accent"
49
+ },
50
+ "black": {
51
+ "hex": "#000000",
52
+ "tier": "neutral"
53
+ },
54
+ "ink": {
55
+ "hex": "#332E27",
56
+ "tier": "neutral"
57
+ },
58
+ "gray-dark": {
59
+ "hex": "#7A6E67",
60
+ "tier": "neutral"
61
+ },
62
+ "gray": {
63
+ "hex": "#9E968D",
64
+ "tier": "neutral"
65
+ },
66
+ "gray-light": {
67
+ "hex": "#C5B9AC",
68
+ "tier": "neutral"
69
+ },
70
+ "gray-faint": {
71
+ "hex": "#D6D1CA",
72
+ "tier": "neutral"
73
+ }
74
+ }
@@ -0,0 +1,11 @@
1
+ import * as react from 'react';
2
+
3
+ declare function SwatchGrid(): react.JSX.Element;
4
+
5
+ declare function Combinator({ assetBase }: {
6
+ assetBase: string;
7
+ }): react.JSX.Element;
8
+
9
+ declare function Sampler(): react.JSX.Element;
10
+
11
+ export { Combinator, Sampler, SwatchGrid };