diff --git a/slave variables documentation - Pregmod.txt b/slave variables documentation - Pregmod.txt
index 259dcf0f9834e019ecfadebe3b937860c2ffa726..3955d0dbcd73e5642889e3bb9928755a0a856412 100644
--- a/slave variables documentation - Pregmod.txt	
+++ b/slave variables documentation - Pregmod.txt	
@@ -2091,7 +2091,21 @@ Does this slave refer to you rudely?
 
 customImage:
 
-hold custom img link?
+holds the custom slave image file name (used if images are enabled)
+accepts string
+default 0 (no custom image)
+
+customImageFormat:
+
+holds the custom slave image file format.
+one of "png", "jpg", "gif" or "webm"
+default "png"
+
+customHairVector:
+
+holds the custom hair vector base file name (used if vector images are enabled)
+accepts string
+default 0 (use hardcoded hair styles)
 
 currentRules: []
 
diff --git a/src/init/dummy.tw b/src/init/dummy.tw
index 49de2bb24cec1b57d4851d335073f8e4386bd51d..ef8aca46adcb79d368105b5ed039a70089cb3169 100644
--- a/src/init/dummy.tw
+++ b/src/init/dummy.tw
@@ -21,7 +21,7 @@ $belarusianSlaveNames, $dominicanSlaveNames, $scottishSlaveNames
 $ArcologyNamesEugenics, $ArcologyNamesRepopulationist, $ArcologyNamesHedonisticDecadence
 $hare1, $hare2, $hare3, $hareSpeed, $hareSpeed1, $hareSpeed2, $hareSpeed3, $origin1, $origin2, $origin3, $LurcherSpeed
 $$i
-$activeSlave.bodySwap, $activeSlave.customImageFormat
+$activeSlave.bodySwap, $activeSlave.customImageFormat, $activeSlave.customHairVector
 $drugs
 $PC.origRace, $PC.origSkin
 */
diff --git a/src/uncategorized/addCustomDescriptors.tw b/src/uncategorized/addCustomDescriptors.tw
index a00876ec992b7cbedc456e165eea2e83dcfb43b4..8ee47b6f4727f34fe69ccc8c04707b55a8df4f06 100644
--- a/src/uncategorized/addCustomDescriptors.tw
+++ b/src/uncategorized/addCustomDescriptors.tw
@@ -155,4 +155,15 @@ jQuery(function() {
 			jQuery("#customImageFormatValue").text(this.value);
 		});
 });
-<</script>>
\ No newline at end of file
+<</script>>
+<<if $seeImages == 1 && $imageChoice == 1>>
+	<br><br>
+	<<if ndef $activeSlave.customHairVector>><<set $activeSlave.customHairVector = 0>><</if>>
+	Assign her a custom hair SVG image:
+	<<if $activeSlave.customHairVector != 0>>
+		<<textbox "$activeSlave.customHairVector" $activeSlave.customHairVector "Add custom descriptors">>
+	<<else>>
+		<<textbox "$activeSlave.customHairVector" "" "Add custom descriptors">>
+	<</if>>
+	<<link "Reset">><<set $activeSlave.customHairVector = 0>><<goto "Add custom descriptors">><</link>>
+<</if>>
\ No newline at end of file
diff --git a/src/utility/artWidgets.tw b/src/utility/artWidgets.tw
index 8202cc0a42c6ed89d02acc9ada2492be33feb41a..4bd2721427e15de85f334990a5ef37905f3fce4f 100644
--- a/src/utility/artWidgets.tw
+++ b/src/utility/artWidgets.tw
@@ -50,7 +50,7 @@ $args[2]: icon UI Display for vector art, 1 for on.
 %/
 <<widget "SlaveArt">>
 /* This is a nasty workaround for Chrome not rendering overlaid SVG images properly */
-<<run setTimeout(function() { jQuery('.imageRef').fadeTo(1, 0.999); }, 1000)>>
+<<run jQuery(function() { jQuery('.imageRef').imagesLoaded().always(function() { jQuery('.imageRef').fadeTo(1, 0.999); }); })>>
 <<if ndef $args[0].customImage>><<set $args[0].customImage = 0>><</if>>
 <<if $args[0].customImage != 0>>
 
@@ -88,7 +88,11 @@ $args[2]: icon UI Display for vector art, 1 for on.
 <<set _hairFilter = "filter: url(#hair-" + _.kebabCase($args[0].hColor) + ");">>
 <<set _pubesFilter = "filter: url(#hair-" + _.kebabCase($args[0].pubicHColor) + ");">>
 <<set _axillaryFilter = "filter: url(#hair-" + _.kebabCase($args[0].underArmHColor) + ");">>
-<<set _hairStyle = ["neat", "ponytail", "messy"].includes($args[0].hStyle) ? $args[0].hStyle : "neat">>
+<<if $args[0].customHairVector>>
+	<<set _hairStyle = $args[0].customHairVector>>
+<<else>>
+	<<set _hairStyle = ["neat", "ponytail", "messy"].includes($args[0].hStyle) ? $args[0].hStyle : "neat">>
+<</if>>
 
 <<set _imgSkinLoc = _folderLoc + "/body/white">>