diff --git a/docs/handpaint-batch2-shu-spearman-source-v3.png b/docs/handpaint-batch2-shu-spearman-source-v3.png new file mode 100644 index 0000000..bbeecff Binary files /dev/null and b/docs/handpaint-batch2-shu-spearman-source-v3.png differ diff --git a/docs/handpaint-batch2-shu-spearman-v3-animation.gif b/docs/handpaint-batch2-shu-spearman-v3-animation.gif new file mode 100644 index 0000000..8c1b38d Binary files /dev/null and b/docs/handpaint-batch2-shu-spearman-v3-animation.gif differ diff --git a/docs/handpaint-batch2-shu-spearman-v3-battle-browser-check.png b/docs/handpaint-batch2-shu-spearman-v3-battle-browser-check.png new file mode 100644 index 0000000..85696a9 Binary files /dev/null and b/docs/handpaint-batch2-shu-spearman-v3-battle-browser-check.png differ diff --git a/docs/handpaint-batch2-shu-spearman-v3-battle-composite.png b/docs/handpaint-batch2-shu-spearman-v3-battle-composite.png new file mode 100644 index 0000000..5939c50 Binary files /dev/null and b/docs/handpaint-batch2-shu-spearman-v3-battle-composite.png differ diff --git a/docs/handpaint-batch2-shu-spearman-v3-before-after.png b/docs/handpaint-batch2-shu-spearman-v3-before-after.png new file mode 100644 index 0000000..eb5fa76 Binary files /dev/null and b/docs/handpaint-batch2-shu-spearman-v3-before-after.png differ diff --git a/docs/handpaint-batch2-shu-spearman-v3-browser-check.png b/docs/handpaint-batch2-shu-spearman-v3-browser-check.png new file mode 100644 index 0000000..fe70e68 Binary files /dev/null and b/docs/handpaint-batch2-shu-spearman-v3-browser-check.png differ diff --git a/docs/handpaint-batch2-shu-spearman-v3-contact.png b/docs/handpaint-batch2-shu-spearman-v3-contact.png new file mode 100644 index 0000000..cf76df4 Binary files /dev/null and b/docs/handpaint-batch2-shu-spearman-v3-contact.png differ diff --git a/docs/handpaint-batch2-shu-spearman-v3-debug-preview-battle-check.png b/docs/handpaint-batch2-shu-spearman-v3-debug-preview-battle-check.png new file mode 100644 index 0000000..85696a9 Binary files /dev/null and b/docs/handpaint-batch2-shu-spearman-v3-debug-preview-battle-check.png differ diff --git a/docs/handpaint-batch2-shu-spearman-v3-report.md b/docs/handpaint-batch2-shu-spearman-v3-report.md new file mode 100644 index 0000000..65c3d84 --- /dev/null +++ b/docs/handpaint-batch2-shu-spearman-v3-report.md @@ -0,0 +1,24 @@ +# Shu Spearman Sample v3 + +- source: `handpaint-batch2-shu-spearman-source-v3.png` +- base status: ok +- action status: ok +- base partial alpha: 0, opaque pixels: 1829476 +- action partial alpha: 0, opaque pixels: 4242447 +- base frame border hits: 0 +- action frame border hits: 0 +- base empty frames: 0 +- action empty frames: 0 +- base bbox width range: 146..263 +- base bbox height range: 274..290 +- base bottom range: 303..303 +- action bbox width range: 146..276 +- action bbox height range: 280..295 +- action bottom range: 303..303 +- contact: `handpaint-batch2-shu-spearman-v3-contact.png` +- animation: `handpaint-batch2-shu-spearman-v3-animation.gif` +- before/after: `handpaint-batch2-shu-spearman-v3-before-after.png` +- scale compare: `handpaint-batch2-shu-spearman-v3-scale-compare.png` +- battle composite: `handpaint-batch2-shu-spearman-v3-battle-composite.png` +- manual checks: run build and local browser verification after generation +- note: battle composite is a scale review image; gameplay roster is unchanged during sample approval diff --git a/docs/handpaint-batch2-shu-spearman-v3-scale-compare.png b/docs/handpaint-batch2-shu-spearman-v3-scale-compare.png new file mode 100644 index 0000000..30b6164 Binary files /dev/null and b/docs/handpaint-batch2-shu-spearman-v3-scale-compare.png differ diff --git a/docs/unit-sprite-art-quality-gate.md b/docs/unit-sprite-art-quality-gate.md index 7213d36..d74b258 100644 --- a/docs/unit-sprite-art-quality-gate.md +++ b/docs/unit-sprite-art-quality-gate.md @@ -6,9 +6,9 @@ This gate catches obvious sprite-art failures before user approval. It does not - Manifest: `docs/unit-sprite-rework-manifest.json` - Audit: `docs/unit-sprite-rework-audit.json` -- Approved baseline units: 7 +- Approved baseline units: 8 - Pending approval units: 0 -- Queued rework units: 84 +- Queued rework units: 83 ## Checked Rules diff --git a/docs/unit-sprite-current-approval-board.png b/docs/unit-sprite-current-approval-board.png new file mode 100644 index 0000000..f0f3748 Binary files /dev/null and b/docs/unit-sprite-current-approval-board.png differ diff --git a/docs/unit-sprite-next-steps.md b/docs/unit-sprite-next-steps.md index 85653c6..124f2b8 100644 --- a/docs/unit-sprite-next-steps.md +++ b/docs/unit-sprite-next-steps.md @@ -4,9 +4,9 @@ This file is generated by `scripts/write-unit-sprite-next-steps.py`. ## Current Gate -- Approved baseline units: 7 +- Approved baseline units: 8 - Pending approval units: 0 -- Queued rework units: 84 +- Queued rework units: 83 - Manifest: `docs/unit-sprite-rework-manifest.json` - Audit: `docs/unit-sprite-rework-audit.json` - Current approval board: not generated until the next pending sample. @@ -14,11 +14,10 @@ This file is generated by `scripts/write-unit-sprite-next-steps.py`. ## Next Unit Queue -1. `unit-shu-spearman` - queued-rework, base `border-hits=32`, actions `border-hits=82`, spec `unit-sprite-batch2-shu-spearman-spec.md` -2. `unit-shu-archer` - queued-rework, base `border-hits=64`, actions `border-hits=140`, spec `unit-sprite-batch2-shu-archer-spec.md` -3. `unit-shu-cavalry` - queued-rework, base `border-hits=64`, actions `border-hits=144`, spec `unit-sprite-batch2-shu-cavalry-spec.md` -4. `unit-shu-strategist` - queued-rework, base `border-hits=32`, actions `border-hits=98`, spec `unit-sprite-batch2-shu-strategist-spec.md` -5. `unit-shu-officer` - queued-rework, base `border-hits=32`, actions `border-hits=82`, spec `unit-sprite-batch2-shu-officer-spec.md` +1. `unit-shu-archer` - queued-rework, base `border-hits=64`, actions `border-hits=140`, spec `unit-sprite-batch2-shu-archer-spec.md` +2. `unit-shu-cavalry` - queued-rework, base `border-hits=64`, actions `border-hits=144`, spec `unit-sprite-batch2-shu-cavalry-spec.md` +3. `unit-shu-strategist` - queued-rework, base `border-hits=32`, actions `border-hits=98`, spec `unit-sprite-batch2-shu-strategist-spec.md` +4. `unit-shu-officer` - queued-rework, base `border-hits=32`, actions `border-hits=82`, spec `unit-sprite-batch2-shu-officer-spec.md` ## Commands Before Approval @@ -45,6 +44,6 @@ pnpm build ## First Task After Current Approval -- Start with `unit-shu-spearman`. -- Use spec: `unit-sprite-batch2-shu-spearman-spec.md`. +- Start with `unit-shu-archer`. +- Use spec: `unit-sprite-batch2-shu-archer-spec.md`. - Generate source art, assemble sheets, produce contact/GIF/before-after/scale/battle screenshots, then rerun the gates. diff --git a/docs/unit-sprite-review-approved-and-pending.png b/docs/unit-sprite-review-approved-and-pending.png index 80f8b10..cc7a9d3 100644 Binary files a/docs/unit-sprite-review-approved-and-pending.png and b/docs/unit-sprite-review-approved-and-pending.png differ diff --git a/docs/unit-sprite-review-batch2-shu.png b/docs/unit-sprite-review-batch2-shu.png index d34b0a5..41d7e86 100644 Binary files a/docs/unit-sprite-review-batch2-shu.png and b/docs/unit-sprite-review-batch2-shu.png differ diff --git a/docs/unit-sprite-review-index.png b/docs/unit-sprite-review-index.png index c5701de..7217276 100644 Binary files a/docs/unit-sprite-review-index.png and b/docs/unit-sprite-review-index.png differ diff --git a/docs/unit-sprite-rework-audit.json b/docs/unit-sprite-rework-audit.json index 000c35d..791d023 100644 --- a/docs/unit-sprite-rework-audit.json +++ b/docs/unit-sprite-rework-audit.json @@ -11,8 +11,8 @@ "batch7-unique-officer": 19 }, "stage_counts": { - "approved-baseline": 7, - "queued-rework": 84 + "approved-baseline": 8, + "queued-rework": 83 }, "rows": [ { @@ -2639,7 +2639,7 @@ }, { "batch": "batch2-shu", - "review_stage": "queued-rework", + "review_stage": "approved-baseline", "stem": "unit-shu-spearman", "base": { "key": "unit-shu-spearman", @@ -2649,23 +2649,23 @@ 1252 ], "partial_alpha": 0, - "opaque_pixels": 2000768, - "border_hits": 32, - "min_width": 194, - "max_width": 254, - "min_height": 279, - "max_height": 279, - "min_bottom": 281, - "max_bottom": 287, + "opaque_pixels": 1829476, + "border_hits": 0, + "min_width": 146, + "max_width": 263, + "min_height": 274, + "max_height": 290, + "min_bottom": 303, + "max_bottom": 303, "empty_frames": 0, - "width_swing": 60, - "height_swing": 0, - "bottom_swing": 6, - "battle_min_width_px": 31.0, - "battle_max_width_px": 40.6, - "battle_min_height_px": 44.6, - "battle_max_height_px": 44.6, - "status": "border-hits=32" + "width_swing": 117, + "height_swing": 16, + "bottom_swing": 0, + "battle_min_width_px": 23.3, + "battle_max_width_px": 42.0, + "battle_min_height_px": 43.8, + "battle_max_height_px": 46.3, + "status": "ok" }, "actions": { "key": "unit-shu-spearman-actions", @@ -2675,23 +2675,23 @@ 1252 ], "partial_alpha": 0, - "opaque_pixels": 4471927, - "border_hits": 82, - "min_width": 194, - "max_width": 263, - "min_height": 275, - "max_height": 279, - "min_bottom": 274, - "max_bottom": 289, + "opaque_pixels": 4242447, + "border_hits": 0, + "min_width": 146, + "max_width": 276, + "min_height": 280, + "max_height": 295, + "min_bottom": 303, + "max_bottom": 303, "empty_frames": 0, - "width_swing": 69, - "height_swing": 4, - "bottom_swing": 15, - "battle_min_width_px": 31.0, - "battle_max_width_px": 42.0, - "battle_min_height_px": 43.9, - "battle_max_height_px": 44.6, - "status": "border-hits=82" + "width_swing": 130, + "height_swing": 15, + "bottom_swing": 0, + "battle_min_width_px": 23.3, + "battle_max_width_px": 44.1, + "battle_min_height_px": 44.7, + "battle_max_height_px": 47.1, + "status": "ok" } }, { diff --git a/docs/unit-sprite-rework-audit.md b/docs/unit-sprite-rework-audit.md index 3fb2687..b20d6d5 100644 --- a/docs/unit-sprite-rework-audit.md +++ b/docs/unit-sprite-rework-audit.md @@ -29,8 +29,8 @@ Visual review boards are generated by `scripts/render-unit-sprite-review-boards. ## Review Stage Counts -- approved-baseline: 7 -- queued-rework: 84 +- approved-baseline: 8 +- queued-rework: 83 ## Batch Plan @@ -98,7 +98,7 @@ Visual review boards are generated by `scripts/render-unit-sprite-review-boards. | batch2-shu | queued-rework | `unit-shu-officer` | border-hits=32 | border-hits=82 | 200..254 x 279..279 | 200..263 x 275..279 | 31.9..40.6 x 44.6..44.6 | w54 h0 b6 | | batch2-shu | queued-rework | `unit-shu-officer-council` | border-hits=32 | border-hits=82 | 200..254 x 279..279 | 200..263 x 275..279 | 31.9..40.6 x 44.6..44.6 | w54 h0 b6 | | batch2-shu | queued-rework | `unit-shu-officer-vanguard` | border-hits=64 | border-hits=144 | 208..258 x 282..288 | 208..267 x 275..290 | 33.2..41.2 x 45.0..46.0 | w50 h6 b6 | -| batch2-shu | queued-rework | `unit-shu-spearman` | border-hits=32 | border-hits=82 | 194..254 x 279..279 | 194..263 x 275..279 | 31.0..40.6 x 44.6..44.6 | w60 h0 b6 | +| batch2-shu | approved-baseline | `unit-shu-spearman` | ok | ok | 146..263 x 274..290 | 146..276 x 280..295 | 23.3..42.0 x 43.8..46.3 | w117 h16 b0 | | batch2-shu | queued-rework | `unit-shu-spearman-guard` | border-hits=64 | border-hits=144 | 202..258 x 282..288 | 202..267 x 275..290 | 32.3..41.2 x 45.0..46.0 | w56 h6 b6 | | batch2-shu | queued-rework | `unit-shu-spearman-veteran` | border-hits=64 | border-hits=144 | 202..258 x 282..288 | 202..267 x 275..290 | 32.3..41.2 x 45.0..46.0 | w56 h6 b6 | | batch2-shu | queued-rework | `unit-shu-strategist` | border-hits=32 | border-hits=98 | 243..246 x 280..281 | 220..255 x 275..281 | 38.8..39.3 x 44.7..44.9 | w3 h1 b6 | diff --git a/docs/unit-sprite-rework-manifest.json b/docs/unit-sprite-rework-manifest.json index b4b6217..eb2fad7 100644 --- a/docs/unit-sprite-rework-manifest.json +++ b/docs/unit-sprite-rework-manifest.json @@ -17,12 +17,12 @@ "unit-rebel-archer", "unit-rebel-cavalry", "unit-shu-infantry", + "unit-shu-spearman", "unit-zhang-fei" ], "pendingApproval": [], "currentApprovalCandidate": {}, "nextAfterApproval": [ - "unit-shu-spearman", "unit-shu-archer", "unit-shu-cavalry", "unit-shu-strategist", diff --git a/docs/unit-sprite-shu-spearman-v3-approval-packet.md b/docs/unit-sprite-shu-spearman-v3-approval-packet.md new file mode 100644 index 0000000..e52bff8 --- /dev/null +++ b/docs/unit-sprite-shu-spearman-v3-approval-packet.md @@ -0,0 +1,85 @@ +# Shu Spearman v3 Approval Packet + +This packet records the approved `unit-shu-spearman` Batch 2 Shu quality baseline. + +## Decision Target + +- Unit: `unit-shu-spearman` +- Batch: Batch 2 Shu generic units +- Status: approved by user +- Review stage: `approved-baseline` +- Review manifest: `unit-sprite-rework-manifest.json` +- Art quality gate: `unit-sprite-art-quality-gate.md` +- Next unit after approval: `unit-shu-archer` +- Commit/push/deploy: allowed after release gate verification + +## Visual Evidence + +- Approval board at review time: `unit-sprite-current-approval-board.png` +- Source art: `handpaint-batch2-shu-spearman-source-v3.png` +- Contact sheet: `handpaint-batch2-shu-spearman-v3-contact.png` +- Animation GIF: `handpaint-batch2-shu-spearman-v3-animation.gif` +- v2/v3 comparison: `handpaint-batch2-shu-spearman-v3-before-after.png` +- 50px/72px scale comparison: `handpaint-batch2-shu-spearman-v3-scale-compare.png` +- Battle-scale map composite: `handpaint-batch2-shu-spearman-v3-battle-composite.png` +- Local browser title check: `handpaint-batch2-shu-spearman-v3-browser-check.png` +- Local browser first battle check: `handpaint-batch2-shu-spearman-v3-battle-browser-check.png` +- Local browser debug sprite preview: `handpaint-batch2-shu-spearman-v3-debug-preview-battle-check.png` +- Approved/pending deliverables board: `unit-sprite-review-approved-and-pending.png` +- Batch 2 inventory board: `unit-sprite-review-batch2-shu.png` +- Review index: `unit-sprite-review-index.png` + +## Technical Evidence + +- Base sheet: `src/assets/images/units/unit-shu-spearman.png` +- Action sheet: `src/assets/images/units/unit-shu-spearman-actions.png` +- Base sheet size: `5008x1252` +- Action sheet size: `11268x1252` +- Base partial alpha: `0` +- Action partial alpha: `0` +- Base frame border hits: `0` +- Action frame border hits: `0` +- Base frame empty count: `0` +- Action frame empty count: `0` +- Base bbox range: `146..263 x 274..290` +- Action bbox range: `146..276 x 280..295` +- Base bottom range: `303..303` +- Action bottom range: `303..303` +- Audit status: `ok` + +## Completed Verification + +- `python scripts/assemble-handpaint-shu-infantry-quality-sample.py --source docs\handpaint-batch2-shu-spearman-source-v3.png --stem unit-shu-spearman --work-dir tmp\handpaint-shu-spearman-v3 --output-prefix handpaint-batch2-shu-spearman-v3 --fit-width-scale 1.12 --min-frame-height 274` +- `pnpm build` +- Local browser app load passed at `http://127.0.0.1:4173/heros_web/?debug&debugSpritePreview=unit-shu-spearman&v=shu-spearman-v3-final` +- Local browser first battle load passed at the same URL. +- Local browser debug sprite preview passed at the same URL. +- Local browser console errors: `0` +- Technical alpha/border/bbox inspection passed +- Build and browser verification passed locally. +- Release gate passed after approval. + +## Quality Note + +This v3 candidate replaced v1 and v2 and is approved as the current Shu spearman baseline. v1 had strong spear identity but made the body feel slightly small at 50px; v2 improved stability but still had narrow front-facing silhouettes. v3 widens the front body block, keeps the spear class identity obvious, and better matches the approved Shu infantry v8 scale while preserving the 313px frame format. + +Approved because: + +- It reads clearly as a spear unit at the 50px battle size. +- It feels close enough to the approved Liu Bei/Guan Yu/Zhang Fei/Rebel/Shu infantry v8 direction. +- The spear line, green Shu armor, helmet, and foot-soldier silhouette read before the background. +- The unit does not look ghostly, transparent, low-resolution, too thin, or like a placeholder. +- The user accepted this as the quality bar for continuing Batch 2 spearmen and the next Shu generic unit. + +After approval completed: + +- `unit-shu-spearman` was moved from `pendingApproval` to `approvedBaseline` in `unit-sprite-rework-manifest.json`. +- Audit, review boards, release gate, and build were rerun. +- Next unit: `unit-shu-archer`. + +Reject or request revision if: + +- The body still feels too small next to approved Shu infantry v8. +- The spear tip or shaft feels cropped, detached, or too thin at 50px. +- The style is not close enough to the approved first batch and Shu infantry v8 direction. +- The 50px view is not readable enough for live battle play. diff --git a/scripts/assemble-handpaint-shu-infantry-quality-sample.py b/scripts/assemble-handpaint-shu-infantry-quality-sample.py index 852f033..1b9a02f 100644 --- a/scripts/assemble-handpaint-shu-infantry-quality-sample.py +++ b/scripts/assemble-handpaint-shu-infantry-quality-sample.py @@ -23,6 +23,8 @@ REPORT_TITLE = "Shu Infantry Quality Restart Sample v3" SAMPLE_LABEL = "shu sample" COMPARE_STEMS = ["unit-liu-bei", "unit-guan-yu", "unit-zhang-fei", "unit-rebel", STEM] COMPARE_LABELS = ["liu-bei", "guan-yu", "zhang-fei", "rebel", "shu-infantry"] +FIT_WIDTH_SCALE = 1.0 +MIN_FRAME_HEIGHT = 0 FRAME = 313 DIRECTIONS = ("south", "east", "north", "west") BASE_FRAMES_PER_DIRECTION = 16 @@ -186,7 +188,18 @@ def solidify_alpha(image: Image.Image) -> Image.Image: return Image.fromarray(arr, "RGBA") +def grow_to_minimum_height(subject: Image.Image, max_width: int, max_height: int) -> Image.Image: + if MIN_FRAME_HEIGHT <= 0 or subject.height >= MIN_FRAME_HEIGHT: + return subject + grow = min(max_width / subject.width, max_height / subject.height, MIN_FRAME_HEIGHT / subject.height) + if grow <= 1: + return subject + size = (max(1, round(subject.width * grow)), max(1, round(subject.height * grow))) + return trim_to_alpha(solidify_alpha(subject.resize(size, Image.Resampling.LANCZOS))) + + def fit_frame(source: Image.Image, max_width: int, max_height: int, bottom: int = 304, x_offset: int = 0, allow_detached_effects = False) -> Image.Image: + max_width = int(round(max_width * FIT_WIDTH_SCALE)) subject = crop_subject(source, allow_detached_effects) if subject.width <= 1 or subject.height <= 1: return Image.new("RGBA", (FRAME, FRAME), (0, 0, 0, 0)) @@ -194,9 +207,11 @@ def fit_frame(source: Image.Image, max_width: int, max_height: int, bottom: int size = (max(1, round(subject.width * scale)), max(1, round(subject.height * scale))) subject = solidify_alpha(subject.resize(size, Image.Resampling.LANCZOS)) subject = trim_to_alpha(subject) + subject = grow_to_minimum_height(subject, max_width, max_height) if not allow_detached_effects: subject = keep_largest_component(subject) subject = trim_to_alpha(subject) + subject = grow_to_minimum_height(subject, max_width, max_height) frame = Image.new("RGBA", (FRAME, FRAME), (0, 0, 0, 0)) x = (FRAME - subject.width) // 2 + x_offset y = bottom - subject.height @@ -517,6 +532,8 @@ def parse_args() -> argparse.Namespace: parser.add_argument("--sample-label", default=SAMPLE_LABEL) parser.add_argument("--compare-stems", default=",".join(COMPARE_STEMS)) parser.add_argument("--compare-labels", default=",".join(COMPARE_LABELS)) + parser.add_argument("--fit-width-scale", type=float, default=FIT_WIDTH_SCALE) + parser.add_argument("--min-frame-height", type=int, default=MIN_FRAME_HEIGHT) return parser.parse_args() @@ -524,6 +541,7 @@ def configure(args: argparse.Namespace) -> None: global SOURCE, WORK_DIR, BATTLE_REFERENCE, STEM, OUTPUT_PREFIX global CONTACT_TITLE, BEFORE_TITLE, BEFORE_SCALE_LABEL, REPORT_TITLE, SAMPLE_LABEL global COMPARE_STEMS, COMPARE_LABELS + global FIT_WIDTH_SCALE, MIN_FRAME_HEIGHT SOURCE = project_path(args.source) WORK_DIR = project_path(args.work_dir) @@ -537,6 +555,8 @@ def configure(args: argparse.Namespace) -> None: SAMPLE_LABEL = args.sample_label COMPARE_STEMS = split_csv(args.compare_stems) COMPARE_LABELS = split_csv(args.compare_labels) + FIT_WIDTH_SCALE = args.fit_width_scale + MIN_FRAME_HEIGHT = args.min_frame_height if len(COMPARE_STEMS) != len(COMPARE_LABELS): raise ValueError("--compare-stems and --compare-labels must have the same number of entries") diff --git a/scripts/render-current-sprite-approval-board.py b/scripts/render-current-sprite-approval-board.py index de7bb2c..70b9836 100644 --- a/scripts/render-current-sprite-approval-board.py +++ b/scripts/render-current-sprite-approval-board.py @@ -72,12 +72,12 @@ def write_text_block(draw: ImageDraw.ImageDraw, x: int, y: int, lines: list[str] draw.text((x, y + index * 21), line, fill=fill, font=small) -def render_board() -> Path: +def render_board() -> Path | None: manifest = load_json(MANIFEST_PATH) audit = load_json(AUDIT_PATH) pending = manifest.get("pendingApproval", []) if not pending: - raise ValueError("no pendingApproval unit to render") + return None stem = pending[0] candidates = manifest.get("currentApprovalCandidate", {}) @@ -151,6 +151,9 @@ def render_board() -> Path: def main() -> None: path = render_board() + if path is None: + print("Skipped current approval board: no pendingApproval unit to render") + return print(f"Wrote {path}") diff --git a/src/assets/images/units/unit-shu-spearman-actions.png b/src/assets/images/units/unit-shu-spearman-actions.png index b4ab915..b7a3da2 100644 Binary files a/src/assets/images/units/unit-shu-spearman-actions.png and b/src/assets/images/units/unit-shu-spearman-actions.png differ diff --git a/src/assets/images/units/unit-shu-spearman.png b/src/assets/images/units/unit-shu-spearman.png index 049185d..9ebaf39 100644 Binary files a/src/assets/images/units/unit-shu-spearman.png and b/src/assets/images/units/unit-shu-spearman.png differ