egregore-artifacts 0.2.0 → 0.4.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.
@@ -5,7 +5,7 @@ import {
5
5
  TextBlock, ArtifactFooter,
6
6
  } from '../components.js';
7
7
  import { renderMarkdownLite } from '../markdown.js';
8
- import { colors, fonts } from '../tokens.js';
8
+ import { fonts } from '../tokens.js';
9
9
 
10
10
  const h = React.createElement;
11
11
 
@@ -38,7 +38,7 @@ export function handoffTemplate(handoff) {
38
38
  marginBottom: '1.5rem',
39
39
  fontFamily: fonts.mono,
40
40
  fontSize: '13px',
41
- color: colors.muted,
41
+ color: 'var(--muted)',
42
42
  },
43
43
  },
44
44
  h('span', null, 'To:'),
@@ -47,9 +47,9 @@ export function handoffTemplate(handoff) {
47
47
  key: i,
48
48
  style: {
49
49
  padding: '2px 10px',
50
- background: 'rgba(123, 157, 183, 0.1)',
50
+ background: 'var(--blue-chip)',
51
51
  borderRadius: '50px',
52
- color: colors.blueMuted,
52
+ color: 'var(--blue-muted)',
53
53
  fontSize: '12px',
54
54
  fontWeight: 500,
55
55
  },
@@ -71,14 +71,14 @@ export function handoffTemplate(handoff) {
71
71
  marginBottom: '2rem',
72
72
  fontFamily: fonts.mono,
73
73
  fontSize: '12px',
74
- color: colors.muted,
74
+ color: 'var(--muted)',
75
75
  },
76
76
  },
77
77
  handoff.source && h('span', null, `Source: ${handoff.source}`),
78
78
  handoff.branch && h('span', {
79
79
  style: {
80
80
  padding: '2px 8px',
81
- background: 'rgba(59, 45, 33, 0.06)',
81
+ background: 'var(--subtle-fill)',
82
82
  borderRadius: '4px',
83
83
  fontFamily: fonts.mono,
84
84
  },
@@ -143,7 +143,7 @@ export function handoffTemplate(handoff) {
143
143
  display: 'flex',
144
144
  gap: '12px',
145
145
  padding: '8px 0',
146
- borderBottom: i < handoff.nextSteps.length - 1 ? '1px solid rgba(224, 216, 204, 0.5)' : 'none',
146
+ borderBottom: i < handoff.nextSteps.length - 1 ? '1px solid var(--hairline)' : 'none',
147
147
  fontSize: '15px',
148
148
  lineHeight: 1.5,
149
149
  },
@@ -154,8 +154,8 @@ export function handoffTemplate(handoff) {
154
154
  width: '24px',
155
155
  height: '24px',
156
156
  borderRadius: '50%',
157
- background: colors.terracotta,
158
- color: colors.cream,
157
+ background: 'var(--terracotta)',
158
+ color: 'var(--cream)',
159
159
  display: 'flex',
160
160
  alignItems: 'center',
161
161
  justifyContent: 'center',
@@ -0,0 +1,189 @@
1
+ // Network/people data → React element tree with role filter tabs
2
+ import React from 'react';
3
+ import { ArtifactHeader, SectionCard, ArtifactFooter } from '../components.js';
4
+ import { fonts } from '../tokens.js';
5
+
6
+ const h = React.createElement;
7
+
8
+ // Semantic role colors — hex here is fine because these are node labels,
9
+ // not theme surfaces. They ride on top of whichever background is active
10
+ // and are readable against both light and dark due to white text.
11
+ const ROLE_COLORS = {
12
+ 'Alpha Tester': '#D4875A',
13
+ 'Design Partner': '#2A7B5B',
14
+ 'Champion': '#8B5CF6',
15
+ 'Comms Amplifier': '#E08B4A',
16
+ 'Code Contributor': '#3B82F6',
17
+ 'Feedback': '#7B9DB7',
18
+ 'Logo Wall': '#16100B',
19
+ 'Investor/Partner': '#B45309',
20
+ };
21
+
22
+ function RoleBadge({ role }) {
23
+ const bg = ROLE_COLORS[role] || 'var(--muted)';
24
+ return h('span', {
25
+ style: {
26
+ fontFamily: fonts.mono, fontSize: '10px', padding: '2px 8px',
27
+ borderRadius: '4px', background: bg, color: 'white',
28
+ whiteSpace: 'nowrap', fontWeight: 500,
29
+ },
30
+ }, role);
31
+ }
32
+
33
+ function PersonRow({ person }) {
34
+ return h('div', {
35
+ style: {
36
+ display: 'grid',
37
+ gridTemplateColumns: '180px 220px 1fr',
38
+ gap: '16px',
39
+ alignItems: 'start',
40
+ padding: '14px 16px',
41
+ borderBottom: '1px solid var(--border)',
42
+ },
43
+ },
44
+ // Name + org column
45
+ h('div', { style: { overflow: 'hidden' } },
46
+ h('div', { style: { fontSize: '14px', fontWeight: 600, color: 'var(--black)' } }, person.name),
47
+ person.organization && h('div', {
48
+ style: { fontFamily: fonts.mono, fontSize: '11px', color: 'var(--muted)', marginTop: '2px' },
49
+ }, person.organization),
50
+ ),
51
+ // Roles column
52
+ h('div', {
53
+ style: { display: 'flex', gap: '4px', flexWrap: 'wrap', paddingTop: '2px' },
54
+ },
55
+ ...(person.roles || []).map((role, i) =>
56
+ h(RoleBadge, { key: i, role })
57
+ ),
58
+ ),
59
+ // Notes column
60
+ h('div', {
61
+ style: { fontSize: '13px', color: 'var(--dark)', lineHeight: 1.5 },
62
+ }, person.notes),
63
+ );
64
+ }
65
+
66
+ function RoleTabs({ allRoles, summary }) {
67
+ return h('div', {
68
+ style: {
69
+ display: 'flex', gap: '4px', marginBottom: '1.5rem', flexWrap: 'wrap',
70
+ borderBottom: '2px solid var(--border)', paddingBottom: '0',
71
+ },
72
+ },
73
+ h('button', {
74
+ className: 'eg-network-tab',
75
+ 'data-role': 'all',
76
+ style: {
77
+ fontFamily: fonts.mono, fontSize: '12px', padding: '6px 12px',
78
+ background: 'none', border: 'none', borderBottom: '2px solid transparent',
79
+ marginBottom: '-2px', cursor: 'pointer', color: 'var(--muted)',
80
+ },
81
+ }, `All (${summary.totalPeople})`),
82
+ ...allRoles.map(role =>
83
+ h('button', {
84
+ key: role,
85
+ className: 'eg-network-tab',
86
+ 'data-role': role,
87
+ style: {
88
+ fontFamily: fonts.mono, fontSize: '12px', padding: '6px 12px',
89
+ background: 'none', border: 'none', borderBottom: '2px solid transparent',
90
+ marginBottom: '-2px', cursor: 'pointer', color: 'var(--muted)',
91
+ },
92
+ }, `${role} (${summary.byRole[role]})`)
93
+ ),
94
+ );
95
+ }
96
+
97
+ export function networkTemplate(data) {
98
+ const sections = [];
99
+
100
+ sections.push(
101
+ h(ArtifactHeader, {
102
+ key: 'header',
103
+ title: data.title,
104
+ type: 'network',
105
+ date: data.date,
106
+ author: data.updatedBy,
107
+ status: 'active',
108
+ priority: 0,
109
+ projects: [],
110
+ })
111
+ );
112
+
113
+ sections.push(h(RoleTabs, { key: 'tabs', allRoles: data.allRoles, summary: data.summary }));
114
+
115
+ // Column headers
116
+ sections.push(
117
+ h('div', {
118
+ key: 'col-headers',
119
+ style: {
120
+ display: 'grid',
121
+ gridTemplateColumns: '180px 220px 1fr',
122
+ gap: '16px',
123
+ padding: '8px 16px',
124
+ borderBottom: '2px solid var(--border)',
125
+ fontFamily: fonts.mono, fontSize: '10px', textTransform: 'uppercase',
126
+ letterSpacing: '0.06em', color: 'var(--muted)', fontWeight: 600,
127
+ },
128
+ },
129
+ h('span', null, 'Name'),
130
+ h('span', null, 'Role'),
131
+ h('span', null, 'Notes'),
132
+ )
133
+ );
134
+
135
+ // All people rows — each tagged with data-roles for filtering
136
+ sections.push(
137
+ h('div', { key: 'people', id: 'eg-network-list' },
138
+ ...data.people.map((person, i) =>
139
+ h('div', {
140
+ key: i,
141
+ className: 'eg-network-person',
142
+ 'data-roles': (person.roles || []).join(','),
143
+ },
144
+ h(PersonRow, { person })
145
+ )
146
+ ),
147
+ )
148
+ );
149
+
150
+ // Tab switching script
151
+ sections.push(
152
+ h('script', {
153
+ key: 'tabs-script',
154
+ dangerouslySetInnerHTML: {
155
+ __html: `
156
+ (function() {
157
+ var tabs = document.querySelectorAll('.eg-network-tab');
158
+ var people = document.querySelectorAll('.eg-network-person');
159
+ function activate(role) {
160
+ tabs.forEach(function(t) {
161
+ var active = t.dataset.role === role;
162
+ t.style.color = active ? 'var(--black)' : 'var(--muted)';
163
+ t.style.borderBottomColor = active ? 'var(--terracotta)' : 'transparent';
164
+ t.style.fontWeight = active ? '600' : '400';
165
+ });
166
+ people.forEach(function(p) {
167
+ if (role === 'all') { p.style.display = 'block'; return; }
168
+ var roles = p.dataset.roles || '';
169
+ p.style.display = roles.split(',').indexOf(role) >= 0 ? 'block' : 'none';
170
+ });
171
+ }
172
+ tabs.forEach(function(t) { t.addEventListener('click', function() { activate(t.dataset.role); }); });
173
+ activate('all');
174
+ })();
175
+ `,
176
+ },
177
+ })
178
+ );
179
+
180
+ sections.push(
181
+ h(ArtifactFooter, {
182
+ key: 'footer',
183
+ generatedAt: new Date().toISOString(),
184
+ source: 'memory/network/people.json',
185
+ })
186
+ );
187
+
188
+ return h('div', null, ...sections);
189
+ }
package/lib/tokens.js CHANGED
@@ -18,6 +18,18 @@ export const colors = {
18
18
  accent: '#D4875A',
19
19
  secondary: '#7B9DB7',
20
20
 
21
+ // Dark mode
22
+ darkBg: '#1D1611',
23
+ darkBgCard: '#241E19',
24
+ darkBgCode: '#161210',
25
+ darkBgElevated: '#2A231D',
26
+ darkText: 'rgba(255, 255, 255, 0.92)',
27
+ darkTextSoft: 'rgba(255, 255, 255, 0.75)',
28
+ darkTextMuted: 'rgba(255, 255, 255, 0.50)',
29
+ darkTextDim: 'rgba(255, 255, 255, 0.30)',
30
+ darkBorder: 'rgba(255, 255, 255, 0.06)',
31
+ darkBorderStrong: 'rgba(255, 255, 255, 0.10)',
32
+
21
33
  // Terminal syntax
22
34
  terminalHighlight: '#E7794B',
23
35
  terminalSuccess: '#6BBF6B',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "egregore-artifacts",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "Generate branded HTML artifacts from Egregore data",
5
5
  "type": "module",
6
6
  "license": "MIT",