@pareto4/pp-core 1.7.0 → 1.8.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/.claude-plugin/plugin.json +1 -1
- package/bin/install.js +116 -0
- package/commands/pp-build-handoff.md +46 -0
- package/commands/pp-discovery-to-build.md +40 -0
- package/gemini-extension.json +1 -1
- package/package.json +2 -1
- package/pareto-skills/_shared/create-project-board.sh +195 -0
- package/pareto-skills/_shared/pp-claude-md-protocol.md +306 -0
- package/pareto-skills/_shared/sync-phase-status.sh +139 -0
- package/pareto-skills/pp-brand/SKILL.md +644 -0
- package/pareto-skills/pp-brand/assets/crew/ParetoAgent.inline.html +120 -0
- package/pareto-skills/pp-brand/assets/crew/ParetoAgent.tsx +239 -0
- package/pareto-skills/pp-brand/assets/crew/build.svg +11 -0
- package/pareto-skills/pp-brand/assets/crew/deploy.svg +11 -0
- package/pareto-skills/pp-brand/assets/crew/discovery.svg +11 -0
- package/pareto-skills/pp-brand/assets/crew/plan.svg +11 -0
- package/pareto-skills/pp-brand/assets/crew/run.svg +11 -0
- package/pareto-skills/pp-brand/assets/crew/validate.svg +11 -0
- package/pareto-skills/pp-brand/assets/pareto-brand-preview.html +547 -0
- package/pareto-skills/pp-obsidian-notes/SKILL.md +127 -0
- package/pareto-skills/pp-obsidian-notes/templates/CLAUDE.md +29 -0
- package/pareto-skills/pp-obsidian-notes/templates/client-context.md +116 -0
- package/pareto-skills/pp-obsidian-notes/templates/meeting-note.md +66 -0
- package/pareto-skills/pp-obsidian-notes/templates/pareto-context.md +102 -0
- package/pareto-skills/pp-obsidian-notes/templates/proposal.md +117 -0
- package/pareto-skills/pp-project-setup/SKILL.md +1364 -0
- package/pp-core/bin/lib/intel.cjs +1 -1
- package/pp-core/bin/lib/io.cjs +120 -0
- package/pp-core/bin/lib/profile-pipeline-command-router.cjs +1 -1
- package/pp-core/bin/lib/roadmap-parser.cjs +1 -1
- package/pp-core/bin/lib/runtime-artifact-conversion.cjs +2 -2
- package/pp-core/bin/lib/surface.cjs +1 -1
- package/pp-core/bin/lib/worktree-safety.cjs +2 -2
- package/pp-core/bin/pp-tools.cjs +23 -0
- package/pp-core/references/ui-brand.md +73 -11
- package/pp-core/templates/codebase/structure.md +5 -5
- package/pp-core/templates/spec.md +7 -7
- package/pp-core/workflows/add-backlog.md +1 -1
- package/pp-core/workflows/autonomous.md +4 -4
- package/pp-core/workflows/debug.md +1 -1
- package/pp-core/workflows/discovery-to-build.md +598 -0
- package/pp-core/workflows/execute-phase.md +9 -1
- package/pp-core/workflows/plan-phase.md +14 -12
- package/pp-core/workflows/pr-branch.md +5 -4
- package/pp-core/workflows/reapply-patches.md +1 -1
- package/pp-core/workflows/ship.md +1 -1
- package/pp-core/workflows/thread.md +1 -1
- package/pp-core/workflows/verify-work.md +6 -5
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Pareto Crew — vanilla HTML/CSS snippet.
|
|
3
|
+
Copy-paste anywhere (emails, docs, plain HTML pages, slide exports).
|
|
4
|
+
No JS required. Self-contained styles scoped under .pareto-agent.
|
|
5
|
+
|
|
6
|
+
One agent per delivery PHASE — no character names.
|
|
7
|
+
Change data-role to one of: discovery · plan · build · validate · deploy · run
|
|
8
|
+
…and swap the <g class="pa-acc"> accessory to match (snippets at the bottom).
|
|
9
|
+
Change --pa-size to any px/rem.
|
|
10
|
+
|
|
11
|
+
Note: the cursor-tracking pupils need JS — use assets/crew/ParetoAgent.tsx
|
|
12
|
+
for the full interactive behaviour. This static snippet keeps eyes at rest.
|
|
13
|
+
|
|
14
|
+
Respects prefers-reduced-motion.
|
|
15
|
+
-->
|
|
16
|
+
|
|
17
|
+
<style>
|
|
18
|
+
.pareto-agent {
|
|
19
|
+
--pa-size: 200px;
|
|
20
|
+
--pa-body: #2251FF;
|
|
21
|
+
--pa-antenna: #F6B437;
|
|
22
|
+
display: inline-flex;
|
|
23
|
+
flex-direction: column;
|
|
24
|
+
align-items: center;
|
|
25
|
+
gap: 10px;
|
|
26
|
+
}
|
|
27
|
+
/* Phase body colors */
|
|
28
|
+
.pareto-agent[data-role="discovery"] { --pa-body: #F6B437; --pa-antenna: #2251FF; }
|
|
29
|
+
.pareto-agent[data-role="plan"] { --pa-body: #146FF4; }
|
|
30
|
+
.pareto-agent[data-role="build"] { --pa-body: #2251FF; }
|
|
31
|
+
.pareto-agent[data-role="validate"] { --pa-body: #3ECF8E; }
|
|
32
|
+
.pareto-agent[data-role="deploy"] { --pa-body: #FF6B4A; }
|
|
33
|
+
.pareto-agent[data-role="run"] { --pa-body: #A884FF; }
|
|
34
|
+
|
|
35
|
+
.pareto-agent svg { width: var(--pa-size); height: var(--pa-size); display: block; }
|
|
36
|
+
.pareto-agent .pa-body-fill { fill: var(--pa-body); }
|
|
37
|
+
.pareto-agent .pa-antenna-fill { fill: var(--pa-antenna); }
|
|
38
|
+
|
|
39
|
+
.pareto-agent .pa-svg { animation: pa-bob 3.4s ease-in-out infinite; transform-origin: center bottom; }
|
|
40
|
+
.pareto-agent .pa-antenna { transform-origin: 70px 7px; animation: pa-pulse 2.2s ease-in-out infinite; }
|
|
41
|
+
.pareto-agent .pa-eye { transform-origin: center; transform-box: fill-box; animation: pa-blink 5s ease-in-out infinite; }
|
|
42
|
+
.pareto-agent .pa-eye-r { animation-delay: 0.08s; }
|
|
43
|
+
.pareto-agent .pa-smile { transform-origin: 70px 94px; animation: pa-smile 4s ease-in-out infinite; }
|
|
44
|
+
|
|
45
|
+
.pareto-agent[data-role="discovery"] .pa-acc { transform-origin: 104px 34px; animation: pa-scan 3.2s ease-in-out infinite; }
|
|
46
|
+
.pareto-agent[data-role="plan"] .pa-acc { transform-origin: 103px 88px; animation: pa-tick 3.4s ease-in-out infinite; }
|
|
47
|
+
.pareto-agent[data-role="build"] .pa-acc { transform-origin: 70px 30px; animation: pa-tip 3.6s ease-in-out infinite; }
|
|
48
|
+
.pareto-agent[data-role="validate"] .pa-acc { transform-origin: 103px 88px; animation: pa-tick 3.2s ease-in-out infinite; }
|
|
49
|
+
.pareto-agent[data-role="deploy"] .pa-acc { transform-origin: 109px 35px; animation: pa-fly 1.8s ease-in-out infinite; }
|
|
50
|
+
.pareto-agent[data-role="run"] .pa-acc { transform-origin: 106px 100px; animation: pa-rev 2.4s ease-in-out infinite; }
|
|
51
|
+
|
|
52
|
+
.pareto-agent[data-role="discovery"] .pa-svg { animation-delay: 0s; }
|
|
53
|
+
.pareto-agent[data-role="plan"] .pa-svg { animation-delay: 0.3s; }
|
|
54
|
+
.pareto-agent[data-role="build"] .pa-svg { animation-delay: 0.6s; }
|
|
55
|
+
.pareto-agent[data-role="validate"] .pa-svg { animation-delay: 0.9s; }
|
|
56
|
+
.pareto-agent[data-role="deploy"] .pa-svg { animation-delay: 1.2s; }
|
|
57
|
+
.pareto-agent[data-role="run"] .pa-svg { animation-delay: 1.5s; }
|
|
58
|
+
|
|
59
|
+
@keyframes pa-bob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-4px); } }
|
|
60
|
+
@keyframes pa-pulse { 0%,100% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.3); opacity: 0.85; } }
|
|
61
|
+
@keyframes pa-blink { 0%,92%,100% { transform: scaleY(1); } 94%,98% { transform: scaleY(0.1); } }
|
|
62
|
+
@keyframes pa-smile { 0%,100% { transform: scaleX(1); } 50% { transform: scaleX(1.08) translateY(-1px); } }
|
|
63
|
+
@keyframes pa-tip { 0%,80%,100% { transform: translateY(0) rotate(0); } 40%,60% { transform: translateY(-2px) rotate(-4deg); } }
|
|
64
|
+
@keyframes pa-tick { 0%,60%,100% { transform: translateY(0) rotate(0); } 70%,80% { transform: translateY(-2px) rotate(-4deg); } }
|
|
65
|
+
@keyframes pa-fly { 0%,100% { transform: translate(0,0) rotate(0); } 50% { transform: translate(3px,-4px) rotate(10deg); } }
|
|
66
|
+
@keyframes pa-scan { 0%,100% { transform: translate(0,0) rotate(0); } 50% { transform: translate(-3px,2px) rotate(-8deg); } }
|
|
67
|
+
@keyframes pa-rev { 0%,100% { transform: rotate(-6deg); } 50% { transform: rotate(8deg); } }
|
|
68
|
+
|
|
69
|
+
@media (prefers-reduced-motion: reduce) {
|
|
70
|
+
.pareto-agent *, .pareto-agent .pa-svg { animation: none !important; }
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.pareto-agent__label {
|
|
74
|
+
font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
75
|
+
font-size: 11px;
|
|
76
|
+
letter-spacing: 0.16em;
|
|
77
|
+
text-transform: uppercase;
|
|
78
|
+
color: var(--pa-body);
|
|
79
|
+
}
|
|
80
|
+
</style>
|
|
81
|
+
|
|
82
|
+
<!-- Build agent (default). Swap data-role + the <g class="pa-acc"> accessory below. -->
|
|
83
|
+
<div class="pareto-agent" data-role="build" style="--pa-size: 200px;">
|
|
84
|
+
<svg class="pa-svg" viewBox="0 0 140 140" fill="none" aria-label="Build — Pareto agent">
|
|
85
|
+
<rect x="20" y="26" width="100" height="90" rx="28" class="pa-body-fill"/>
|
|
86
|
+
<path d="M70 10 L70 26" stroke-width="4" stroke-linecap="round" style="stroke: var(--pa-body);"/>
|
|
87
|
+
<circle class="pa-antenna pa-antenna-fill" cx="70" cy="7" r="5"/>
|
|
88
|
+
<g class="pa-eye pa-eye-l"><circle cx="52" cy="66" r="8" fill="#fff"/><circle cx="53" cy="68" r="4" fill="#0A1330"/></g>
|
|
89
|
+
<g class="pa-eye pa-eye-r"><circle cx="88" cy="66" r="8" fill="#fff"/><circle cx="89" cy="68" r="4" fill="#0A1330"/></g>
|
|
90
|
+
<path class="pa-smile" d="M58 90 Q70 100 82 90" stroke="#0A1330" stroke-width="3" stroke-linecap="round" fill="none"/>
|
|
91
|
+
<!-- Accessory: BUILD (hard hat) -->
|
|
92
|
+
<g class="pa-acc">
|
|
93
|
+
<path d="M34 30 Q70 14 106 30 L106 34 L34 34 Z" fill="#F6B437"/>
|
|
94
|
+
<rect x="68" y="16" width="4" height="14" fill="#E0920C"/>
|
|
95
|
+
</g>
|
|
96
|
+
</svg>
|
|
97
|
+
<span class="pareto-agent__label">Build</span>
|
|
98
|
+
</div>
|
|
99
|
+
|
|
100
|
+
<!--
|
|
101
|
+
ACCESSORIES — paste the matching <g class="pa-acc"> for the chosen data-role:
|
|
102
|
+
|
|
103
|
+
DISCOVERY (magnifying glass):
|
|
104
|
+
<g class="pa-acc"><circle cx="104" cy="34" r="7" fill="none" stroke="#0A1330" stroke-width="3"/><path d="M109 39 L117 47" stroke="#0A1330" stroke-width="3" stroke-linecap="round"/></g>
|
|
105
|
+
|
|
106
|
+
PLAN (blueprint):
|
|
107
|
+
<g class="pa-acc"><rect x="92" y="74" width="22" height="28" rx="2" fill="#fff" stroke="#0A1330" stroke-width="1.5"/><path d="M96 80h14M96 86h14M96 92h9" stroke="#146FF4" stroke-width="1.4" stroke-linecap="round"/><path d="M101 74v28" stroke="#0A1330" stroke-width="1" stroke-dasharray="2 2"/></g>
|
|
108
|
+
|
|
109
|
+
BUILD (hard hat):
|
|
110
|
+
<g class="pa-acc"><path d="M34 30 Q70 14 106 30 L106 34 L34 34 Z" fill="#F6B437"/><rect x="68" y="16" width="4" height="14" fill="#E0920C"/></g>
|
|
111
|
+
|
|
112
|
+
VALIDATE (checklist):
|
|
113
|
+
<g class="pa-acc"><rect x="92" y="74" width="22" height="28" rx="2" fill="#fff" stroke="#0A1330" stroke-width="1.5"/><rect x="97" y="70" width="12" height="7" rx="1" fill="#0A1330"/><path d="M96 88 l4 4 7-8" stroke="#1D9E75" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/></g>
|
|
114
|
+
|
|
115
|
+
DEPLOY (rocket):
|
|
116
|
+
<g class="pa-acc"><path d="M102 40 L116 26 L112 44 Z" fill="#2251FF"/><path d="M110 34 L118 42" stroke="#F6B437" stroke-width="2.5" stroke-linecap="round"/></g>
|
|
117
|
+
|
|
118
|
+
RUN (gauge):
|
|
119
|
+
<g class="pa-acc"><path d="M94 100 a13 13 0 0 1 24 0" fill="none" stroke="#0A1330" stroke-width="2.5" stroke-linecap="round"/><path d="M106 100 L114 91" stroke="#0A1330" stroke-width="2.5" stroke-linecap="round"/><circle cx="106" cy="100" r="2.4" fill="#0A1330"/></g>
|
|
120
|
+
-->
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { useEffect, useRef, type CSSProperties } from 'react'
|
|
4
|
+
|
|
5
|
+
// One agent per pipeline phase. No character names — the phase is the identity.
|
|
6
|
+
type Role = 'hero' | 'discovery' | 'plan' | 'build' | 'validate' | 'deploy' | 'run'
|
|
7
|
+
|
|
8
|
+
interface Props {
|
|
9
|
+
role?: Role
|
|
10
|
+
size?: number
|
|
11
|
+
label?: string
|
|
12
|
+
animate?: boolean
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const BODY: Record<Role, string> = {
|
|
16
|
+
hero: '#2251FF', // Pareto Blue
|
|
17
|
+
discovery: '#F6B437', // Amber — human-led
|
|
18
|
+
plan: '#146FF4', // Steel
|
|
19
|
+
build: '#2251FF', // Pareto Blue
|
|
20
|
+
validate: '#3ECF8E', // Mint — human-led
|
|
21
|
+
deploy: '#FF6B4A', // Coral
|
|
22
|
+
run: '#A884FF', // Violet
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const ROLE_LABEL: Record<Role, string> = {
|
|
26
|
+
hero: 'Pareto', discovery: 'Discovery', plan: 'Plan', build: 'Build',
|
|
27
|
+
validate: 'Validate', deploy: 'Deploy', run: 'Run',
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Eye geometry in the 140×140 viewBox. Pupils track the cursor around the
|
|
31
|
+
// white-of-eye centre (wx/wy); MAX_TRAVEL keeps the pupil inside the white.
|
|
32
|
+
const EYES = {
|
|
33
|
+
left: { wx: 52, wy: 66 },
|
|
34
|
+
right: { wx: 88, wy: 66 },
|
|
35
|
+
}
|
|
36
|
+
const MAX_TRAVEL = 3
|
|
37
|
+
|
|
38
|
+
export default function ParetoAgent({
|
|
39
|
+
role = 'hero',
|
|
40
|
+
size = 200,
|
|
41
|
+
label,
|
|
42
|
+
animate = true,
|
|
43
|
+
}: Props) {
|
|
44
|
+
const color = BODY[role]
|
|
45
|
+
const antennaDot = role === 'discovery' ? '#2251FF' : '#F6B437'
|
|
46
|
+
|
|
47
|
+
const svgRef = useRef<SVGSVGElement>(null)
|
|
48
|
+
const leftPupil = useRef<SVGCircleElement>(null)
|
|
49
|
+
const rightPupil = useRef<SVGCircleElement>(null)
|
|
50
|
+
|
|
51
|
+
// Pupils follow the mouse. rAF-throttled, and disabled under reduced-motion.
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
if (typeof window === 'undefined') return
|
|
54
|
+
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return
|
|
55
|
+
|
|
56
|
+
let raf = 0
|
|
57
|
+
let pending: { x: number; y: number } | null = null
|
|
58
|
+
|
|
59
|
+
const apply = () => {
|
|
60
|
+
raf = 0
|
|
61
|
+
const svg = svgRef.current
|
|
62
|
+
if (!svg || !pending) return
|
|
63
|
+
const rect = svg.getBoundingClientRect()
|
|
64
|
+
if (!rect.width) return
|
|
65
|
+
const scale = rect.width / 140
|
|
66
|
+
const { x, y } = pending
|
|
67
|
+
|
|
68
|
+
const aim = (pupil: SVGCircleElement | null, e: { wx: number; wy: number }) => {
|
|
69
|
+
if (!pupil) return
|
|
70
|
+
const cx = rect.left + e.wx * scale
|
|
71
|
+
const cy = rect.top + e.wy * scale
|
|
72
|
+
const dx = x - cx
|
|
73
|
+
const dy = y - cy
|
|
74
|
+
const dist = Math.hypot(dx, dy) || 1
|
|
75
|
+
const travel = Math.min(MAX_TRAVEL, dist / scale)
|
|
76
|
+
pupil.setAttribute('cx', String(e.wx + (dx / dist) * travel))
|
|
77
|
+
pupil.setAttribute('cy', String(e.wy + (dy / dist) * travel))
|
|
78
|
+
}
|
|
79
|
+
aim(leftPupil.current, EYES.left)
|
|
80
|
+
aim(rightPupil.current, EYES.right)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const onMove = (ev: MouseEvent) => {
|
|
84
|
+
pending = { x: ev.clientX, y: ev.clientY }
|
|
85
|
+
if (!raf) raf = requestAnimationFrame(apply)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
window.addEventListener('mousemove', onMove, { passive: true })
|
|
89
|
+
return () => {
|
|
90
|
+
window.removeEventListener('mousemove', onMove)
|
|
91
|
+
if (raf) cancelAnimationFrame(raf)
|
|
92
|
+
}
|
|
93
|
+
}, [])
|
|
94
|
+
|
|
95
|
+
const wrap: CSSProperties = {
|
|
96
|
+
display: 'inline-flex',
|
|
97
|
+
flexDirection: 'column',
|
|
98
|
+
alignItems: 'center',
|
|
99
|
+
gap: 10,
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return (
|
|
103
|
+
<div style={wrap} data-pareto-agent={role}>
|
|
104
|
+
<style>{css(animate)}</style>
|
|
105
|
+
|
|
106
|
+
<svg
|
|
107
|
+
ref={svgRef}
|
|
108
|
+
className="pa-svg"
|
|
109
|
+
width={size}
|
|
110
|
+
height={size}
|
|
111
|
+
viewBox="0 0 140 140"
|
|
112
|
+
fill="none"
|
|
113
|
+
aria-label={`${ROLE_LABEL[role]} — Pareto agent`}
|
|
114
|
+
>
|
|
115
|
+
{/* Body */}
|
|
116
|
+
<rect x="20" y="26" width="100" height="90" rx="28" fill={color} />
|
|
117
|
+
|
|
118
|
+
{/* Antenna */}
|
|
119
|
+
<path d="M70 10 L70 26" stroke={color} strokeWidth="4" strokeLinecap="round" />
|
|
120
|
+
<circle className="pa-antenna" cx="70" cy="7" r="5" fill={antennaDot} />
|
|
121
|
+
|
|
122
|
+
{/* Eyes (pupils track the cursor) */}
|
|
123
|
+
<g className="pa-eye pa-eye-l">
|
|
124
|
+
<circle cx="52" cy="66" r="8" fill="#fff" />
|
|
125
|
+
<circle ref={leftPupil} cx="53" cy="68" r="4" fill="#0A1330" />
|
|
126
|
+
</g>
|
|
127
|
+
<g className="pa-eye pa-eye-r">
|
|
128
|
+
<circle cx="88" cy="66" r="8" fill="#fff" />
|
|
129
|
+
<circle ref={rightPupil} cx="89" cy="68" r="4" fill="#0A1330" />
|
|
130
|
+
</g>
|
|
131
|
+
|
|
132
|
+
{/* Smile */}
|
|
133
|
+
<path
|
|
134
|
+
className="pa-smile"
|
|
135
|
+
d="M58 90 Q70 100 82 90"
|
|
136
|
+
stroke="#0A1330"
|
|
137
|
+
strokeWidth="3"
|
|
138
|
+
strokeLinecap="round"
|
|
139
|
+
fill="none"
|
|
140
|
+
/>
|
|
141
|
+
|
|
142
|
+
{/* Role accessories — one per phase */}
|
|
143
|
+
{role === 'discovery' && (
|
|
144
|
+
<g className="pa-acc pa-magnify">
|
|
145
|
+
<circle cx="104" cy="34" r="7" fill="none" stroke="#0A1330" strokeWidth="3" />
|
|
146
|
+
<path d="M109 39 L117 47" stroke="#0A1330" strokeWidth="3" strokeLinecap="round" />
|
|
147
|
+
</g>
|
|
148
|
+
)}
|
|
149
|
+
{role === 'plan' && (
|
|
150
|
+
<g className="pa-acc pa-plan">
|
|
151
|
+
<rect x="92" y="74" width="22" height="28" rx="2" fill="#fff" stroke="#0A1330" strokeWidth="1.5" />
|
|
152
|
+
<path d="M96 80h14M96 86h14M96 92h9" stroke="#146FF4" strokeWidth="1.4" strokeLinecap="round" />
|
|
153
|
+
<path d="M101 74v28" stroke="#0A1330" strokeWidth="1" strokeDasharray="2 2" />
|
|
154
|
+
</g>
|
|
155
|
+
)}
|
|
156
|
+
{role === 'build' && (
|
|
157
|
+
<g className="pa-acc pa-hardhat">
|
|
158
|
+
<path d="M34 30 Q70 14 106 30 L106 34 L34 34 Z" fill="#F6B437" />
|
|
159
|
+
<rect x="68" y="16" width="4" height="14" fill="#E0920C" />
|
|
160
|
+
</g>
|
|
161
|
+
)}
|
|
162
|
+
{role === 'validate' && (
|
|
163
|
+
<g className="pa-acc pa-clipboard">
|
|
164
|
+
<rect x="92" y="74" width="22" height="28" rx="2" fill="#fff" stroke="#0A1330" strokeWidth="1.5" />
|
|
165
|
+
<rect x="97" y="70" width="12" height="7" rx="1" fill="#0A1330" />
|
|
166
|
+
<path d="M96 88 l4 4 7-8" stroke="#1D9E75" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" fill="none" />
|
|
167
|
+
</g>
|
|
168
|
+
)}
|
|
169
|
+
{role === 'deploy' && (
|
|
170
|
+
<g className="pa-acc pa-rocket">
|
|
171
|
+
<path d="M102 40 L116 26 L112 44 Z" fill="#2251FF" />
|
|
172
|
+
<path d="M110 34 L118 42" stroke="#F6B437" strokeWidth="2.5" strokeLinecap="round" />
|
|
173
|
+
</g>
|
|
174
|
+
)}
|
|
175
|
+
{role === 'run' && (
|
|
176
|
+
<g className="pa-acc pa-gauge">
|
|
177
|
+
<path d="M94 100 a13 13 0 0 1 24 0" fill="none" stroke="#0A1330" strokeWidth="2.5" strokeLinecap="round" />
|
|
178
|
+
<path d="M106 100 L114 91" stroke="#0A1330" strokeWidth="2.5" strokeLinecap="round" />
|
|
179
|
+
<circle cx="106" cy="100" r="2.4" fill="#0A1330" />
|
|
180
|
+
</g>
|
|
181
|
+
)}
|
|
182
|
+
</svg>
|
|
183
|
+
|
|
184
|
+
{label && (
|
|
185
|
+
<span
|
|
186
|
+
style={{
|
|
187
|
+
fontFamily: "var(--font-mono), 'JetBrains Mono', monospace",
|
|
188
|
+
fontSize: 11,
|
|
189
|
+
letterSpacing: '0.16em',
|
|
190
|
+
textTransform: 'uppercase',
|
|
191
|
+
color: color,
|
|
192
|
+
}}
|
|
193
|
+
>
|
|
194
|
+
{label}
|
|
195
|
+
</span>
|
|
196
|
+
)}
|
|
197
|
+
</div>
|
|
198
|
+
)
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function css(animate: boolean) {
|
|
202
|
+
if (!animate) return ''
|
|
203
|
+
return `
|
|
204
|
+
[data-pareto-agent] .pa-svg { animation: pa-bob 3.4s ease-in-out infinite; transform-origin: center bottom; }
|
|
205
|
+
[data-pareto-agent] .pa-antenna { transform-origin: 70px 7px; animation: pa-pulse 2.2s ease-in-out infinite; }
|
|
206
|
+
[data-pareto-agent] .pa-eye { transform-origin: center; transform-box: fill-box; animation: pa-blink 5s ease-in-out infinite; }
|
|
207
|
+
[data-pareto-agent] .pa-eye-r { animation-delay: 0.08s; }
|
|
208
|
+
[data-pareto-agent] .pa-smile { transform-origin: 70px 94px; animation: pa-smile 4s ease-in-out infinite; }
|
|
209
|
+
|
|
210
|
+
[data-pareto-agent="discovery"] .pa-magnify { transform-origin: 104px 34px; animation: pa-scan 3.2s ease-in-out infinite; }
|
|
211
|
+
[data-pareto-agent="plan"] .pa-plan { transform-origin: 103px 88px; animation: pa-tick 3.4s ease-in-out infinite; }
|
|
212
|
+
[data-pareto-agent="build"] .pa-hardhat { transform-origin: 70px 30px; animation: pa-tip 3.6s ease-in-out infinite; }
|
|
213
|
+
[data-pareto-agent="validate"] .pa-clipboard{ transform-origin: 103px 88px; animation: pa-tick 3.2s ease-in-out infinite; }
|
|
214
|
+
[data-pareto-agent="deploy"] .pa-rocket { transform-origin: 109px 35px; animation: pa-fly 1.8s ease-in-out infinite; }
|
|
215
|
+
[data-pareto-agent="run"] .pa-gauge { transform-origin: 106px 100px; animation: pa-rev 2.4s ease-in-out infinite; }
|
|
216
|
+
|
|
217
|
+
/* Stagger so a row of agents isn't in sync */
|
|
218
|
+
[data-pareto-agent="discovery"] .pa-svg { animation-delay: 0s; }
|
|
219
|
+
[data-pareto-agent="plan"] .pa-svg { animation-delay: 0.3s; }
|
|
220
|
+
[data-pareto-agent="build"] .pa-svg { animation-delay: 0.6s; }
|
|
221
|
+
[data-pareto-agent="validate"] .pa-svg { animation-delay: 0.9s; }
|
|
222
|
+
[data-pareto-agent="deploy"] .pa-svg { animation-delay: 1.2s; }
|
|
223
|
+
[data-pareto-agent="run"] .pa-svg { animation-delay: 1.5s; }
|
|
224
|
+
|
|
225
|
+
@keyframes pa-bob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-4px); } }
|
|
226
|
+
@keyframes pa-pulse { 0%,100% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.3); opacity: 0.85; } }
|
|
227
|
+
@keyframes pa-blink { 0%,92%,100% { transform: scaleY(1); } 94%,98% { transform: scaleY(0.1); } }
|
|
228
|
+
@keyframes pa-smile { 0%,100% { transform: scaleX(1); } 50% { transform: scaleX(1.08) translateY(-1px); } }
|
|
229
|
+
@keyframes pa-tip { 0%,80%,100% { transform: translateY(0) rotate(0); } 40%,60% { transform: translateY(-2px) rotate(-4deg); } }
|
|
230
|
+
@keyframes pa-tick { 0%,60%,100% { transform: translateY(0) rotate(0); } 70%,80% { transform: translateY(-2px) rotate(-4deg); } }
|
|
231
|
+
@keyframes pa-fly { 0%,100% { transform: translate(0,0) rotate(0); } 50% { transform: translate(3px,-4px) rotate(10deg); } }
|
|
232
|
+
@keyframes pa-scan { 0%,100% { transform: translate(0,0) rotate(0); } 50% { transform: translate(-3px,2px) rotate(-8deg); } }
|
|
233
|
+
@keyframes pa-rev { 0%,100% { transform: rotate(-6deg); } 50% { transform: rotate(8deg); } }
|
|
234
|
+
|
|
235
|
+
@media (prefers-reduced-motion: reduce) {
|
|
236
|
+
[data-pareto-agent] *, [data-pareto-agent] .pa-svg { animation: none !important; }
|
|
237
|
+
}
|
|
238
|
+
`
|
|
239
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="140" height="140" viewBox="0 0 140 140" fill="none">
|
|
2
|
+
<rect x="20" y="26" width="100" height="90" rx="28" fill="#2251FF"/>
|
|
3
|
+
<path d="M70 10 L70 26" stroke="#2251FF" stroke-width="4" stroke-linecap="round"/>
|
|
4
|
+
<circle cx="70" cy="7" r="5" fill="#F6B437"/>
|
|
5
|
+
<circle cx="52" cy="66" r="8" fill="#fff"/>
|
|
6
|
+
<circle cx="53" cy="68" r="4" fill="#0A1330"/>
|
|
7
|
+
<circle cx="88" cy="66" r="8" fill="#fff"/>
|
|
8
|
+
<circle cx="89" cy="68" r="4" fill="#0A1330"/>
|
|
9
|
+
<path d="M58 90 Q70 100 82 90" stroke="#0A1330" stroke-width="3" stroke-linecap="round" fill="none"/>
|
|
10
|
+
<g><path d="M34 30 Q70 14 106 30 L106 34 L34 34 Z" fill="#F6B437"/><rect x="68" y="16" width="4" height="14" fill="#E0920C"/></g>
|
|
11
|
+
</svg>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="140" height="140" viewBox="0 0 140 140" fill="none">
|
|
2
|
+
<rect x="20" y="26" width="100" height="90" rx="28" fill="#FF6B4A"/>
|
|
3
|
+
<path d="M70 10 L70 26" stroke="#FF6B4A" stroke-width="4" stroke-linecap="round"/>
|
|
4
|
+
<circle cx="70" cy="7" r="5" fill="#F6B437"/>
|
|
5
|
+
<circle cx="52" cy="66" r="8" fill="#fff"/>
|
|
6
|
+
<circle cx="53" cy="68" r="4" fill="#0A1330"/>
|
|
7
|
+
<circle cx="88" cy="66" r="8" fill="#fff"/>
|
|
8
|
+
<circle cx="89" cy="68" r="4" fill="#0A1330"/>
|
|
9
|
+
<path d="M58 90 Q70 100 82 90" stroke="#0A1330" stroke-width="3" stroke-linecap="round" fill="none"/>
|
|
10
|
+
<g><path d="M102 40 L116 26 L112 44 Z" fill="#2251FF"/><path d="M110 34 L118 42" stroke="#F6B437" stroke-width="2.5" stroke-linecap="round"/></g>
|
|
11
|
+
</svg>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="140" height="140" viewBox="0 0 140 140" fill="none">
|
|
2
|
+
<rect x="20" y="26" width="100" height="90" rx="28" fill="#F6B437"/>
|
|
3
|
+
<path d="M70 10 L70 26" stroke="#F6B437" stroke-width="4" stroke-linecap="round"/>
|
|
4
|
+
<circle cx="70" cy="7" r="5" fill="#2251FF"/>
|
|
5
|
+
<circle cx="52" cy="66" r="8" fill="#fff"/>
|
|
6
|
+
<circle cx="53" cy="68" r="4" fill="#0A1330"/>
|
|
7
|
+
<circle cx="88" cy="66" r="8" fill="#fff"/>
|
|
8
|
+
<circle cx="89" cy="68" r="4" fill="#0A1330"/>
|
|
9
|
+
<path d="M58 90 Q70 100 82 90" stroke="#0A1330" stroke-width="3" stroke-linecap="round" fill="none"/>
|
|
10
|
+
<g><circle cx="104" cy="34" r="7" fill="none" stroke="#0A1330" stroke-width="3"/><path d="M109 39 L117 47" stroke="#0A1330" stroke-width="3" stroke-linecap="round"/></g>
|
|
11
|
+
</svg>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="140" height="140" viewBox="0 0 140 140" fill="none">
|
|
2
|
+
<rect x="20" y="26" width="100" height="90" rx="28" fill="#146FF4"/>
|
|
3
|
+
<path d="M70 10 L70 26" stroke="#146FF4" stroke-width="4" stroke-linecap="round"/>
|
|
4
|
+
<circle cx="70" cy="7" r="5" fill="#F6B437"/>
|
|
5
|
+
<circle cx="52" cy="66" r="8" fill="#fff"/>
|
|
6
|
+
<circle cx="53" cy="68" r="4" fill="#0A1330"/>
|
|
7
|
+
<circle cx="88" cy="66" r="8" fill="#fff"/>
|
|
8
|
+
<circle cx="89" cy="68" r="4" fill="#0A1330"/>
|
|
9
|
+
<path d="M58 90 Q70 100 82 90" stroke="#0A1330" stroke-width="3" stroke-linecap="round" fill="none"/>
|
|
10
|
+
<g><rect x="92" y="74" width="22" height="28" rx="2" fill="#fff" stroke="#0A1330" stroke-width="1.5"/><path d="M96 80h14M96 86h14M96 92h9" stroke="#146FF4" stroke-width="1.4" stroke-linecap="round"/><path d="M101 74v28" stroke="#0A1330" stroke-width="1" stroke-dasharray="2 2"/></g>
|
|
11
|
+
</svg>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="140" height="140" viewBox="0 0 140 140" fill="none">
|
|
2
|
+
<rect x="20" y="26" width="100" height="90" rx="28" fill="#A884FF"/>
|
|
3
|
+
<path d="M70 10 L70 26" stroke="#A884FF" stroke-width="4" stroke-linecap="round"/>
|
|
4
|
+
<circle cx="70" cy="7" r="5" fill="#F6B437"/>
|
|
5
|
+
<circle cx="52" cy="66" r="8" fill="#fff"/>
|
|
6
|
+
<circle cx="53" cy="68" r="4" fill="#0A1330"/>
|
|
7
|
+
<circle cx="88" cy="66" r="8" fill="#fff"/>
|
|
8
|
+
<circle cx="89" cy="68" r="4" fill="#0A1330"/>
|
|
9
|
+
<path d="M58 90 Q70 100 82 90" stroke="#0A1330" stroke-width="3" stroke-linecap="round" fill="none"/>
|
|
10
|
+
<g><path d="M94 100 a13 13 0 0 1 24 0" fill="none" stroke="#0A1330" stroke-width="2.5" stroke-linecap="round"/><path d="M106 100 L114 91" stroke="#0A1330" stroke-width="2.5" stroke-linecap="round"/><circle cx="106" cy="100" r="2.4" fill="#0A1330"/></g>
|
|
11
|
+
</svg>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="140" height="140" viewBox="0 0 140 140" fill="none">
|
|
2
|
+
<rect x="20" y="26" width="100" height="90" rx="28" fill="#3ECF8E"/>
|
|
3
|
+
<path d="M70 10 L70 26" stroke="#3ECF8E" stroke-width="4" stroke-linecap="round"/>
|
|
4
|
+
<circle cx="70" cy="7" r="5" fill="#F6B437"/>
|
|
5
|
+
<circle cx="52" cy="66" r="8" fill="#fff"/>
|
|
6
|
+
<circle cx="53" cy="68" r="4" fill="#0A1330"/>
|
|
7
|
+
<circle cx="88" cy="66" r="8" fill="#fff"/>
|
|
8
|
+
<circle cx="89" cy="68" r="4" fill="#0A1330"/>
|
|
9
|
+
<path d="M58 90 Q70 100 82 90" stroke="#0A1330" stroke-width="3" stroke-linecap="round" fill="none"/>
|
|
10
|
+
<g><rect x="92" y="74" width="22" height="28" rx="2" fill="#fff" stroke="#0A1330" stroke-width="1.5"/><rect x="97" y="70" width="12" height="7" rx="1" fill="#0A1330"/><path d="M96 88 l4 4 7-8" stroke="#1D9E75" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/></g>
|
|
11
|
+
</svg>
|