diff --git a/code/modules/client/preference_setup/loadout/loadout_cosmetics_vr.dm b/code/modules/client/preference_setup/loadout/loadout_cosmetics_vr.dm
new file mode 100644
index 00000000000..8a1935d3549
--- /dev/null
+++ b/code/modules/client/preference_setup/loadout/loadout_cosmetics_vr.dm
@@ -0,0 +1,14 @@
+/datum/gear/cosmetic/nailpolish
+ display_name = "nail polish (colorable)"
+ path = /obj/item/weapon/nailpolish
+
+/datum/gear/cosmetic/nailpolish/New()
+ ..()
+ gear_tweaks += gear_tweak_free_color_choice
+
+/datum/gear/cosmetic/nailpolish/spawn_item(var/location, var/metadata)
+ var/obj/item/weapon/nailpolish/polish = ..()
+ polish.set_colour(polish.color)
+ polish.color = null
+ return polish
+
\ No newline at end of file
diff --git a/code/modules/makeup/nailpolish.dm b/code/modules/makeup/nailpolish.dm
new file mode 100644
index 00000000000..95e0fd24cd1
--- /dev/null
+++ b/code/modules/makeup/nailpolish.dm
@@ -0,0 +1,113 @@
+/obj/item/organ/external/var/datum/nail_polish/nail_polish
+
+/obj/item/weapon/nailpolish
+ name = "nail polish"
+ icon = 'icons/obj/nailpolish_vr.dmi'
+ icon_state = "nailpolish"
+ var/colour = "#FF0000"
+ var/icon/top_underlay
+ var/icon/top_underlay_open
+ var/icon/color_underlay
+ var/icon/color_underlay_open
+ var/open = FALSE
+ drop_sound = 'sound/items/drop/glass.ogg'
+ pickup_sound = 'sound/items/pickup/glass.ogg'
+
+/obj/item/weapon/nailpolish/Initialize()
+ . = ..()
+ regenerate_icons()
+
+/obj/item/weapon/nailpolish/proc/regenerate_icons()
+ top_underlay = icon(icon, "top")
+ top_underlay_open = icon(icon, "top-open")
+ color_underlay = icon(icon, "color")
+ color_underlay.Blend(colour, ICON_MULTIPLY)
+ color_underlay_open = icon(icon, "color-open")
+ color_underlay_open.Blend(colour, ICON_MULTIPLY)
+ update_icon()
+
+/obj/item/weapon/nailpolish/proc/set_colour(var/_colour)
+ colour = _colour
+ regenerate_icons()
+
+/obj/item/weapon/nailpolish/attack_self(var/mob/user)
+ open = !open
+ to_chat(user, SPAN_NOTICE("You [open ? "open" : "close"] \the [src]."))
+ update_icon()
+
+/obj/item/weapon/nailpolish/update_icon()
+ . = ..()
+ underlays.Cut()
+ icon_state = "[initial(icon_state)][open ? "-open" : null]"
+ if (open)
+ underlays = list(color_underlay_open, top_underlay_open)
+ else
+ underlays = list(color_underlay, top_underlay)
+
+/obj/item/weapon/nailpolish/proc/get_polish(var/mob/living/carbon/human/target, var/bp)
+ var/static/forbidden_parts
+ if(!forbidden_parts)
+ forbidden_parts = BP_ALL - list(BP_L_HAND, BP_R_HAND, BP_L_FOOT, BP_R_FOOT)
+ if(!istype(target)) // humantypes only for now
+ return FALSE
+ var/obj/item/organ/external/body_part = target.get_organ(bp)
+ if(!body_part)
+ return FALSE
+ var/ico
+ var/icostate
+ if(length(body_part.markings))
+ for(var/mark_name in body_part.markings)
+ var/mark_data = body_part.markings[mark_name]
+ var/datum/sprite_accessory/marking/mark = mark_data["datum"]
+ if(length(mark.body_parts & forbidden_parts))
+ continue
+ ico = mark.icon
+ icostate = "[mark.icon_state]-[bp]"
+ break
+ else
+ ico = 'icons/obj/nailpolish_vr.dmi'
+ icostate = bp
+ if(bp in forbidden_parts)
+ return FALSE
+ return new /datum/nail_polish(ico, icostate, colour)
+
+/obj/item/weapon/nailpolish/attack(var/mob/user, var/mob/living/carbon/human/target)
+ if(!open)
+ return
+
+ if(!istype(target))
+ return
+
+ var/bp = user.zone_sel.selecting
+ var/obj/item/organ/external/body_part = target.get_organ(bp)
+ if(!body_part)
+ to_chat(user, SPAN_WARNING("[target] is missing that limb!"))
+ return
+ if(body_part.nail_polish)
+ to_chat(user, SPAN_NOTICE("[target]'s [body_part.name] already has nail polish on!"))
+ return
+ var/datum/nail_polish/polish = get_polish(target, bp)
+ if(!polish)
+ to_chat(user, SPAN_NOTICE("You can't find any nails on [body_part] to paint."))
+ return
+ if(user == target)
+ user.visible_message("\The [user] paints their nails with \the [src].", "You paint your nails with \the [src].")
+ else
+ if(do_after(user, 2 SECONDS, target))
+ user.visible_message("\The [user] paints \the [target]'s nails with \the [src].", "You paint \the [target]'s nails with \the [src].")
+ else
+ to_chat(user, SPAN_NOTICE("Both you and [target] must stay still!"))
+ return
+ body_part.nail_polish = polish
+ target.update_icons_body()
+
+/datum/nail_polish
+ var/icon = 'icons/obj/nailpolish_vr.dmi'
+ var/icon_state
+ var/color
+
+/datum/nail_polish/New(var/_icon, var/_icon_state, var/_color)
+ icon = _icon
+ icon_state = _icon_state
+ color = _color
+
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index 7f8d44a742e..0b77148d307 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -271,6 +271,11 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
for(var/M in part.markings)
icon_key += "[M][part.markings[M]["color"]]"
+
+ // VOREStation Edit Start
+ if(part.nail_polish)
+ icon_key += "_[part.nail_polish.icon]_[part.nail_polish.icon_state]_[part.nail_polish.color]"
+ // VOREStation Edit End
if(part.robotic >= ORGAN_ROBOT)
icon_key += "2[part.model ? "-[part.model]": ""]"
diff --git a/code/modules/organs/organ_icon.dm b/code/modules/organs/organ_icon.dm
index 7216540734a..d35a5aa5165 100644
--- a/code/modules/organs/organ_icon.dm
+++ b/code/modules/organs/organ_icon.dm
@@ -131,6 +131,15 @@ var/global/list/limb_icon_cache = list()
I.Blend(rgb(h_col[1],h_col[2],h_col[3]), ICON_MULTIPLY) //VOREStation edit
limb_icon_cache[cache_key] = I
mob_icon.Blend(limb_icon_cache[cache_key], ICON_OVERLAY)
+
+ // VOREStation edit start
+ if(nail_polish)
+ var/icon/I = new(nail_polish.icon, nail_polish.icon_state)
+ I.Blend(nail_polish.color, ICON_MULTIPLY)
+ add_overlay(I)
+ mob_icon.Blend(I, ICON_OVERLAY)
+ icon_cache_key += "_[nail_polish.icon]_[nail_polish.icon_state]_[nail_polish.color]"
+ // VOREStation edit end
if(model)
icon_cache_key += "_model_[model]"
diff --git a/icons/obj/nailpolish_vr.dmi b/icons/obj/nailpolish_vr.dmi
new file mode 100644
index 00000000000..1adfe631970
Binary files /dev/null and b/icons/obj/nailpolish_vr.dmi differ
diff --git a/vorestation.dme b/vorestation.dme
index 12e0df6120d..cdc043fe321 100644
--- a/vorestation.dme
+++ b/vorestation.dme
@@ -1851,6 +1851,7 @@
#include "code\modules\client\preference_setup\loadout\loadout_accessories.dm"
#include "code\modules\client\preference_setup\loadout\loadout_accessories_vr.dm"
#include "code\modules\client\preference_setup\loadout\loadout_cosmetics.dm"
+#include "code\modules\client\preference_setup\loadout\loadout_cosmetics_vr.dm"
#include "code\modules\client\preference_setup\loadout\loadout_cyberware.dm"
#include "code\modules\client\preference_setup\loadout\loadout_ears.dm"
#include "code\modules\client\preference_setup\loadout\loadout_eyes.dm"
@@ -2481,6 +2482,7 @@
#include "code\modules\lore_codex\robutt_data\bybrand.dm"
#include "code\modules\lore_codex\robutt_data\main_robutts.dm"
#include "code\modules\lore_codex\robutt_data\more.dm"
+#include "code\modules\makeup\nailpolish.dm"
#include "code\modules\maps\tg\dmm_suite.dm"
#include "code\modules\maps\tg\map_template.dm"
#include "code\modules\maps\tg\map_template_vr.dm"