diff --git a/src/lib/components/artifact/ArtifactEditPane.svelte b/src/lib/components/artifact/ArtifactEditPane.svelte
new file mode 100644
index 00000000..9ba7ea8e
--- /dev/null
+++ b/src/lib/components/artifact/ArtifactEditPane.svelte
@@ -0,0 +1,305 @@
+
+
+
+
+
+
+
+ {#if disabled}
+
+
+ {elementOptions.find((o) => o.value === element)?.label ?? '—'}
+
+ {:else}
+
+ {/if}
+
+
+ {#if canChangeProficiency}
+
+ {#if disabled}
+ {getProficiencyName(proficiency)}
+ {:else}
+
+ {/if}
+
+ {:else}
+
+ {/if}
+
+
+ {#if disabled || isQuirk}
+ {level}
+ {:else}
+
+ {/if}
+
+
+
+ {#if !isQuirk}
+
+
+ {#each [1, 2, 3, 4] as slot}
+
handleSelectModifier(slot)}
+ onUpdateSkill={(update) => handleUpdateSkill(slot, update)}
+ {disabled}
+ />
+ {/each}
+
+
+ {/if}
+
+
+
+
+
+
+
diff --git a/src/lib/components/artifact/ArtifactGradeDisplay.svelte b/src/lib/components/artifact/ArtifactGradeDisplay.svelte
new file mode 100644
index 00000000..a426daac
--- /dev/null
+++ b/src/lib/components/artifact/ArtifactGradeDisplay.svelte
@@ -0,0 +1,237 @@
+
+
+
+
+
+ {#if grade.letter}
+
+
+ {#if showBreakdown && grade.breakdown}
+
+
+ Selection
+ {grade.breakdown.skillSelection}
+
+
+ Strength
+ {grade.breakdown.baseStrength}
+
+
+ Synergy
+ {grade.breakdown.synergy}
+
+
+ {/if}
+
+ {#if showRecommendation && grade.recommendation}
+ {@const action = actionLabels[grade.recommendation.action]}
+
+
{action?.label ?? grade.recommendation.action}
+ {#if grade.recommendation.reason}
+
{grade.recommendation.reason}
+ {/if}
+
+ {/if}
+ {:else}
+
+ {grade.note ?? 'No grade'}
+
+ {/if}
+
+
+
diff --git a/src/lib/components/artifact/ArtifactModifierList.svelte b/src/lib/components/artifact/ArtifactModifierList.svelte
new file mode 100644
index 00000000..0b8d0e7f
--- /dev/null
+++ b/src/lib/components/artifact/ArtifactModifierList.svelte
@@ -0,0 +1,178 @@
+
+
+
+
+
+ {#if skillsQuery.isPending}
+
Loading skills...
+ {:else if skillsQuery.isError}
+
Failed to load skills
+ {:else}
+ {#if positiveSkills.length > 0}
+
+
+
+ {#each positiveSkills as skill (skill.id)}
+
+ {/each}
+
+
+ {/if}
+
+ {#if negativeSkills.length > 0}
+
+
+
+ {#each negativeSkills as skill (skill.id)}
+
+ {/each}
+
+
+ {/if}
+ {/if}
+
+
+
diff --git a/src/lib/components/artifact/ArtifactSkillRow.svelte b/src/lib/components/artifact/ArtifactSkillRow.svelte
new file mode 100644
index 00000000..643f5392
--- /dev/null
+++ b/src/lib/components/artifact/ArtifactSkillRow.svelte
@@ -0,0 +1,223 @@
+
+
+
+
+
+ {#if !skill?.modifier}
+
+
+ {:else}
+
+
+
+
+
+
+
+
+
+
+
+
+ {/if}
+
+
+
diff --git a/src/lib/components/ui/DisclosureRow.svelte b/src/lib/components/ui/DisclosureRow.svelte
new file mode 100644
index 00000000..113da8b8
--- /dev/null
+++ b/src/lib/components/ui/DisclosureRow.svelte
@@ -0,0 +1,139 @@
+
+
+
+
+
+
+