feat(isac): add game data icon management

This commit is contained in:
JB
2026-07-25 12:38:40 -04:00
parent 9f712e7790
commit 7a12b1d740
16 changed files with 323 additions and 39 deletions
+28
View File
@@ -416,6 +416,34 @@ disclosure header always exposes the configured total, uses a textual title,
and rotates the plus indicator when expanded. The full matrix remains keyboard
operable and follows the shared hover, focus-visible, and pressed states.
### Game-data icons
OS Protocols, brand sets, and talents use the shared game-data icon upload
control in their ISAC editors. Existing artwork is previewed and may be
replaced or explicitly removed. Registry identity cells render a compact
thumbnail before the record name and retain a neutral textual fallback when no
icon is configured.
Source artwork must be a transparent SVG, PNG, WebP, or AVIF no larger than
2 MiB. SVG is treated only as an upload source and never served directly.
Accepted images are normalized asynchronously to a metadata-free transparent
256 × 256 WebP with `contain`, preserving the full symbol without avatar-style
cropping. Image labels remain visible in the UI, so icons supplement rather
than replace textual identity. Upload, replace, remove, pending, validation,
focus-visible, and narrow-screen states follow the shared engineered form
language.
For compact editors such as brand sets, place the icon rail beside the record
name and its primary configuration rows instead of giving the upload control a
full-width band. Keep destructive archive controls isolated on the left side of
the action bar and use the established `.moderation-action.danger` treatment;
save and cancel remain grouped on the right.
Archived records that support restoration replace their destructive archive
control with a green outlined `.moderation-action.restore` control in the same
left-side position. The label must explicitly say “Unarchive” or “Restore”;
never communicate restoration by color or icon alone.
The dedicated unique-talent panel uses five interactive diamonds: no filled
diamonds is the base definition, and each selected upgrade adds one fifth of
the base until five upgrades show exactly twice the base effect.
+15
View File
@@ -163,3 +163,18 @@ The unique primary value uses `base × (1 + (level − 1) / 49)` for levels 1–
talent effects use `base × (1 + upgrades / 5)` for zero to five upgrades.
Server actions validate all relationships and append the full owned graph to
the existing `game_data` audit history.
# Game-data icon storage
Talents, brand sets, and OS Protocols reference uploaded artwork through the
polymorphic `game_data_icons` metadata table. Original uploads are never
retained. The shared server pipeline accepts transparent SVG, PNG, WebP, and
AVIF sources, rejects active or externally referenced SVG content, and uses
Sharp’s asynchronous native worker pool to rasterize and normalize every
accepted icon to a transparent 256 × 256 WebP.
Normalized files live beneath the ignored `data/game-icons/` directory and are
served by the validated `/icons/game-data/[type]/[id]` endpoint with immutable
cache headers and MIME sniffing disabled. ISAC save actions process files
before mutation, apply upload or removal after record validation, and include
only safe icon metadata—not image bytes—in their audit snapshots.