2785 lines
168 KiB
Markdown
2785 lines
168 KiB
Markdown
# SHD.build Design System
|
||
|
||
This document defines the visual language for SHD.build, an independent Division
|
||
Resurgence data-and-tools site for builds, guides, game data, news, and
|
||
discussion. New pages use the same tactical intelligence network as the admin
|
||
dashboard. Public pages may use more space and larger editorial typography.
|
||
|
||
## Design principles
|
||
|
||
1. **Tactical.** Use operational language, compact information density,
|
||
restrained status indicators, and precise alignment. Avoid camouflage,
|
||
distressed textures, and decorative weapon imagery in utility interfaces.
|
||
2. **Data first.** Grouping, typography, borders, and spacing establish
|
||
hierarchy. Admin tools use a dependable control surface.
|
||
3. **Orange means action.** SHD orange identifies primary actions, active
|
||
navigation, focus, and important values. It should not cover large areas.
|
||
4. **State is always visible.** Loading, disabled, active, archived, configured,
|
||
error, and success states need both visual and textual indicators.
|
||
5. **Square and engineered.** Panels and controls use square corners, fine
|
||
borders, tight spacing, and deliberate grid alignment.
|
||
6. **Links use interface feedback, not underlines.** Links do not use native
|
||
text underlines. Communicate hover and focus through SHD accent color,
|
||
borders, brightness, and the required focus-visible outline.
|
||
|
||
## Brand identity
|
||
|
||
SHD.build uses the two-color Core Segments identity. The emblem combines the
|
||
orange Division signal with ISAC's analytic role in the product:
|
||
|
||
- Three unequal Signal Orange arc segments form the outer circle. Each segment
|
||
has square ends.
|
||
- The widest break sits in the upper-right quadrant and contains one detached
|
||
Signal Orange square, which represents a data packet.
|
||
- A Field Manual White open square forms the ISAC core at the center.
|
||
|
||
Keep the emblem in Signal Orange and Field Manual White on Operations Black,
|
||
Terminal Black, or another approved dark surface. SHD.build has no one-color
|
||
emblem. Do not close the arc gaps, equalize the segments, remove the data
|
||
packet, fill the ISAC core, add letters to the emblem, or recolor either part.
|
||
Use a dark holding surface or omit the emblem when a placement cannot reproduce
|
||
both colors.
|
||
|
||
The standard lockup pairs the emblem with the heavy angular `SHD.build`
|
||
wordmark. Set `SHD` in Field Manual White and `.build` in Signal Orange. Place
|
||
the uppercase descriptor `RESURGENCE DATA & TOOLS` below the wordmark in
|
||
restrained telemetry type. Do not substitute another descriptor.
|
||
|
||
Use the complete lockup in the 76px global header and shared footer. The header
|
||
uses a 38px emblem; keep the wordmark and descriptor compact enough to preserve
|
||
the navigation grid. Mobile headers may use the emblem alone when the complete
|
||
lockup would crowd navigation. Favicons and app icons use the emblem without
|
||
text. Small-size artwork must retain both colors, widen the arc gaps where the
|
||
pixel grid requires it, and keep the packet and open core distinct.
|
||
|
||
Treat the emblem as decorative when visible `SHD.build` text names the product.
|
||
Give an emblem-only home link the accessible name `SHD.build home`. Preserve the
|
||
approved colors and full opacity in focus, disabled, and compact contexts; use
|
||
text or control styling to communicate state instead of fading the mark. The
|
||
Field Manual White core and Signal Orange arcs must remain distinct from their
|
||
background at every delivered size.
|
||
|
||
### Routed error console
|
||
|
||
Expected HTTP errors and unexpected server faults use one shared SHD exception
|
||
console inside the application shell. The console displays the numeric status,
|
||
an operational title, a safe explanation, request path, node, and
|
||
context-appropriate recovery controls. Common statuses receive distinct
|
||
language: authentication for 401, clearance for 403, lost location for 404,
|
||
conflict for 409, saturation for 429, and service/fault language for 5xx.
|
||
|
||
Orange identifies recoverable request errors and actions; red identifies server
|
||
faults. Do not display stack traces, database messages, credentials, request
|
||
queries, or raw unexpected exceptions. The global error handler gives each
|
||
unexpected server fault a short support reference ID and keeps the full error
|
||
server-side. If the root application shell cannot render, `src/error.html`
|
||
provides a dependency-free SHD fallback surface. Error controls retain square
|
||
geometry, focus-visible treatment, pressed motion, plain-language labels, and
|
||
stacked mobile recovery actions.
|
||
|
||
### Contact relay and legal requests
|
||
|
||
Public support uses the SHD Contact Relay: a broad transmission form and a
|
||
compact destination guide. Two-to-six destinations use the shared
|
||
segmented-choice pattern. Signed-in identity details may be prefilled; people
|
||
who cannot sign in retain access to the public form. Discord community access
|
||
uses a distinct provider-colored card alongside the durable contact channel.
|
||
|
||
The Contact hero resets the global site-header height: semantic page `header`
|
||
elements use content-driven height and spacing instead of the 76-pixel
|
||
navigation-shell constraint. Its title, description, and Discord card align
|
||
within a minimum 230-pixel desktop band before the form grid begins. The Contact
|
||
page itself remains content-height-driven so high-resolution browser zoom does
|
||
not multiply a viewport minimum into a large empty region above the footer.
|
||
|
||
The application frame uses a full-viewport vertical flex stack. The shared
|
||
footer uses automatic top margin. It rests against the bottom edge on short
|
||
routes and follows document flow after longer content. Do not add spacer heights
|
||
only to position the footer. The frame compensates for `--shd-display-scale`
|
||
when calculating its viewport minimum so high-resolution browser zoom does not
|
||
push a short-page footer below the visible edge.
|
||
|
||
Community access in the shared footer uses a compact Discord-branded action with
|
||
the official symbol, provider blue surface, explicit external-link text, and
|
||
visible hover, focus, and pressed feedback. Keep provider branding separate from
|
||
the orange links reserved for SHD navigation and legal resources. Support and
|
||
legal links form a compact horizontal rail that may wrap at intermediate widths
|
||
and becomes a two-column touch-friendly grid on narrow mobile screens.
|
||
|
||
The footer repeats the complete Core Segments lockup used by the global header:
|
||
two-color emblem, Field Manual White `SHD`, Signal Orange `.build`, and the
|
||
`RESURGENCE DATA & TOOLS` descriptor. Do not substitute a plain text wordmark,
|
||
drop either emblem color, or color the complete product name orange.
|
||
|
||
### Platform positioning
|
||
|
||
SHD.build provides Division Resurgence data and tools for players. Primary
|
||
product language and global navigation represent five durable channels: News,
|
||
Database, Builds, Guides, and Builder. Loadout-specific terms remain appropriate
|
||
inside build routes. The global brand descriptor, homepage metadata, hero,
|
||
sign-in introduction, and footer describe the broader toolset.
|
||
|
||
The homepage uses a community-channel grid to establish this information
|
||
architecture. Each channel has an operational code, plain-language purpose, and
|
||
explicit destination. New channels should extend this reusable pattern rather
|
||
than turning the navigation into an undifferentiated list. Honest launch-state
|
||
pages may describe planned capability, but must distinguish queued features from
|
||
live data. Database landing metrics use approved active records, not invented
|
||
activity counts.
|
||
|
||
On desktop the five public destinations remain visible in the global navigation.
|
||
Mobile navigation numbers destinations dynamically so adding a channel cannot
|
||
collide with Inbox, Profile, or ISAC codes. Community channel cards collapse
|
||
from four columns to two and then one; hover color alone never replaces their
|
||
textual destination labels, focus-visible treatment, or pressed feedback.
|
||
|
||
Authenticated desktop account destinations are consolidated into one
|
||
agent-status menu at the right edge of the global header. Its trigger combines
|
||
the agent avatar, display name, online state, unread count, and an explicit
|
||
expanded marker. The menu contains My Profile, Notifications, and Sign Out;
|
||
these actions are not duplicated as standalone desktop header links. The menu
|
||
uses the same square, compact control-surface treatment as the rest of the
|
||
header, with orange reserved for the open/current state and unread count and
|
||
danger color reserved for the Sign Out hover state.
|
||
|
||
The account trigger exposes its expanded and controlled-menu state. Opening the
|
||
menu moves keyboard focus to its first destination; Escape closes it and returns
|
||
focus to the trigger, while an outside click dismisses it. Mobile keeps Profile,
|
||
Notifications, and Sign Out as explicit navigation actions and shows the avatar
|
||
in the signed-in identity block. Avatar imagery supplements rather than replaces
|
||
the textual identity, state, and unread indicators. User avatars are always
|
||
rendered as circular portraits with the restrained orange SHD ring used by the
|
||
Agent Profile; the source image remains square and uses `object-fit: cover` so
|
||
authenticated surfaces crop it consistently.
|
||
|
||
When unread notifications exist on mobile, repeat the compact orange count on
|
||
both the menu trigger and the Notifications destination. The trigger badge sits
|
||
outside the upper-right control edge without changing the hamburger geometry.
|
||
Its accessible name includes the full unread count; the visible badge is hidden
|
||
from assistive technology to avoid announcing the count twice.
|
||
|
||
Oversight reviewers receive a permission-aware cadence console inside
|
||
Notification Preferences. Each available review queue is shown independently and
|
||
uses the shared segmented radio pattern for Immediate, 15-minute, one-hour, or
|
||
daily delivery. Do not expose categories the agent cannot review. Consolidated
|
||
delivery groups queue items rather than issuing repeated messages; daily
|
||
delivery targets 10:00 AM in `America/New_York` so the Eastern wall-clock time
|
||
remains stable across daylight-saving transitions. On mobile, cadence segments
|
||
wrap to two columns and each review category becomes its own row.
|
||
|
||
ISAC System Configuration is a distinct navigation domain from System Oversight.
|
||
It contains operational configuration such as Automated Messages and read-only
|
||
observability such as System Metrics. Automated-message editors use the standard
|
||
horizontal edit lifecycle: successful edits close the editor, validation
|
||
preserves it, and event triggers remain explicit. Content, enabled state,
|
||
post-event delay, primary destination, and up to eight action callouts are
|
||
displayed as structured fields rather than raw JSON.
|
||
|
||
Automated ISAC messages may expose multiple square action callouts in the
|
||
notification inbox and detail view. Callouts wrap on desktop and become
|
||
full-width touch targets on mobile. Each retains a specific verb and
|
||
destination; do not replace the set with a generic “open” action. External
|
||
community actions such as Discord use secure HTTPS destinations while internal
|
||
actions use routed paths.
|
||
|
||
Contact notifications use the mandatory ISAC visual identity because they are
|
||
operational inbound messages. The notification carries a concise preview and a
|
||
specific action to an authorization-checked full record. Full messages never
|
||
appear in URLs. Copyright requests add a yellow legal-detail subpanel, explicit
|
||
attestations, electronic signature, and a direct policy link. Do not visually
|
||
present a submission as a legal determination.
|
||
|
||
The DMCA policy reuses the legal-document/index layout. Copyright and takedown
|
||
links must remain visible in the global footer alongside Contact Us. On mobile,
|
||
contact columns stack, destination segments become full-width 44-pixel rows,
|
||
attestations remain readable, and reply/recovery actions occupy the available
|
||
width.
|
||
|
||
### Builder range controls
|
||
|
||
Configurable numeric rolls use the shared range-value control: a descriptive
|
||
label and current minimum/maximum above a synchronized range slider and direct
|
||
number input. The slider supports fast exploration while the number field
|
||
supports exact entry; both clamp to the currently calculated bounds. Focus uses
|
||
the SHD action border, active slider feedback uses the standard pressed
|
||
brightness treatment, and number fields retain the global select-all-on-focus
|
||
behavior.
|
||
|
||
When an equipment level changes, preserve the configured roll's relative
|
||
position within its previous range instead of resetting it arbitrarily. Mark
|
||
unverified portions of a level curve with both `ESTIMATED` text and the High-end
|
||
yellow caution treatment. Controls stack the slider and direct input at narrow
|
||
mobile widths and must never create horizontal page overflow.
|
||
|
||
Equipment level uses this same synchronized control rather than a standalone
|
||
number field. Changing level remaps base and rolled values to the equivalent
|
||
relative position in the newly calculated range.
|
||
|
||
Gear and weapons always expose exactly two required rolled-Attribute positions.
|
||
Render both positions as persistent numbered rows; do not offer add or remove
|
||
actions. Already selected Attributes are disabled in the other position.
|
||
|
||
Use compact segmented radio controls for the small finite weapon-tier set. Use
|
||
the shared builder radio grid for visually identified Brand Sets and weapon
|
||
talents: transparent icons lead each square engineered option, text remains
|
||
visible, and the selected state uses the orange action edge plus an explicit
|
||
radio state. Talent grids become searchable when their available pool is large.
|
||
On narrow viewports option grids reduce to two columns and then one column so
|
||
labels and 44-pixel-or-larger targets remain usable.
|
||
|
||
## Tokens
|
||
|
||
The canonical tokens live in `src/app.css` under `:root`.
|
||
|
||
| Purpose | Token | Value |
|
||
| ---------------------- | ----------------------- | --------------------------------------------------- |
|
||
| Page background | `--shd-bg` | `#0a0c0d` |
|
||
| Base surface | `--shd-surface` | `#111415` |
|
||
| Raised surface | `--shd-surface-raised` | `#141718` |
|
||
| Modeled-data surface | `--shd-model-surface` | `#0d1213` |
|
||
| Subordinate border | `--shd-border-soft` | `#272c2d` |
|
||
| Primary border | `--shd-border` | `#303536` |
|
||
| Modeled-data border | `--shd-model-border` | `#3b4648` |
|
||
| Interactive boundary | `--shd-border-strong` | `#424849` |
|
||
| Main text | `--shd-text` | `#ecebe5` |
|
||
| Muted text | `--shd-text-muted` | `#858b8d` |
|
||
| SHD action orange | `--shd-orange` | `#f6a821` |
|
||
| Armor surface | `--shd-armor-surface` | `#13211f` |
|
||
| Armor border | `--shd-armor-border` | `#71aaa5` |
|
||
| Armor label | `--shd-armor-label` | `#8eb9b4` |
|
||
| Armor text | `--shd-armor-text` | `#a5d1ca` |
|
||
| Telemetry text floor | `--shd-type-telemetry` | `12px` |
|
||
| Supporting copy floor | `--shd-type-supporting` | `14px` |
|
||
| Ordinary body floor | `--shd-type-body` | `16px` |
|
||
| Adaptive display scale | `--shd-display-scale` | `1` by default; stepped on high-resolution desktops |
|
||
| Monospaced data | `--shd-font-mono` | Cascadia Mono with system monospace fallbacks |
|
||
|
||
### High-resolution display scaling
|
||
|
||
The application uses restrained stepped interface scaling on wide CSS viewports.
|
||
At 2200px, the interface scales to 115%; at 2800px, to 130%; and at 3400px, to
|
||
150%. This maintains the established relationship among typography, controls,
|
||
tables, spacing, hit targets, and fixed-position surfaces.
|
||
|
||
Use the shared `--shd-display-scale` token and the root-level `zoom` treatment;
|
||
do not add module-specific 4K font-size overrides. Responsive layouts below
|
||
2200px remain unchanged. Browser zoom and operating-system display scaling still
|
||
remain available to users and naturally change the effective CSS viewport.
|
||
High-resolution scaling must not introduce horizontal overflow, clipped fixed
|
||
surfaces, or a different semantic hierarchy. Test the standard desktop layout
|
||
and each affected wide breakpoint after changing this policy. | Success |
|
||
`--shd-success` | `#75c08c` | | Destructive/error | `--shd-danger` | `#df8069` |
|
||
| Informational/defensive | `--shd-info` | `#70b9d6` |
|
||
|
||
Use the spacing tokens for new components. Prefer `8px`, `12px`, and `20px`
|
||
gaps. Dashboard controls use the shared `40px` height when practical.
|
||
|
||
## Typography
|
||
|
||
SHD.build self-hosts two type voices through Fontsource packages:
|
||
|
||
- **Barlow** is the operational family for display headings, navigation,
|
||
controls, data, labels, metadata, and general interface copy. Use the shared
|
||
`--shd-font-sans` token instead of declaring local sans-serif stacks.
|
||
- **Source Serif 4** is the editorial family for explanations, introductions,
|
||
guide-like prose, and longer descriptive passages. Use `--shd-font-editorial`;
|
||
do not apply it to controls, tables, metrics, or telemetry labels.
|
||
|
||
Load Barlow weights 400, 600, 700, 800, and 900, plus Source Serif 4 weights 400
|
||
and 600. Both families are self-hosted, keep fallback stacks, and render without
|
||
a third-party font request. Barlow operates the system; Source Serif 4 explains
|
||
it.
|
||
|
||
- Page and module headings are uppercase, heavy, and tightly spaced.
|
||
- Short operational labels, metadata, statuses, and compact actions use the
|
||
shared 12px telemetry floor. Their tracking must not exceed `0.1em`.
|
||
- Supporting descriptions use at least 14px with normal tracking. Ordinary body
|
||
and form copy uses the 16px body floor.
|
||
- High-resolution workspace scaling never justifies smaller source sizes:
|
||
density comes from spacing, connected borders, tone, and weight.
|
||
- Public/editorial copy uses Source Serif 4 for its restrained field-manual
|
||
character and stays within a 45–75 character reading measure.
|
||
- Never use low-contrast tiny text for information required to complete a task.
|
||
|
||
## Layout patterns
|
||
|
||
### Global mobile navigation
|
||
|
||
At viewports up to 900px, replace the hidden desktop link rail and account
|
||
controls with a labeled square `MENU` control in the shared site header.
|
||
Activating it opens a right-side SHD navigation panel over a dismissible
|
||
backdrop. The panel includes Home, each enabled public destination, Sign In or
|
||
My Profile, and ISAC when authorized. Authenticated agents also receive identity
|
||
state and Sign Out inside the panel. Section availability controls both desktop
|
||
and mobile navigation.
|
||
|
||
Use numbered full-width navigation rows, explicit active-route text styling,
|
||
orange action indicators, and minimum 44px interaction targets. Opening moves
|
||
keyboard focus to the first route. Escape, backdrop activation, route changes,
|
||
and the header Close control dismiss the panel. The toggle exposes
|
||
`aria-expanded` and `aria-controls`, the panel has a distinct navigation label,
|
||
and reduced-motion preferences remove icon transitions. Do not make mobile users
|
||
rely on the logo or desktop-only account controls to reach core routes.
|
||
|
||
On phone-sized viewports up to 700px, ISAC module toolbars stack their action
|
||
area beneath the module title. A single Add action spans the available width;
|
||
multiple creation actions share an equal responsive grid. These controls use a
|
||
minimum 48px height, centered labels, and the standard pressed, focus-visible,
|
||
pending, and disabled treatments. Do not leave desktop-sized Add buttons
|
||
squeezed beside long module headings on mobile.
|
||
|
||
### Public pages
|
||
|
||
- Maximum content width: approximately 1400–1640px.
|
||
- Public pages may use larger headings and more generous vertical rhythm.
|
||
- Preserve the grid background and orange accents.
|
||
- Catalogue and editorial pages use `catalogue-hero` for an angular introductory
|
||
panel and may pair it with a compact operational control bar.
|
||
- Community build cards retain the colored top rule, abstract loadout artwork,
|
||
concise tags, agent attribution, and a full-width terminal action.
|
||
|
||
### Command Grid builder
|
||
|
||
The production builder uses Command Grid as its loadout workbench. Keep the
|
||
entire build visible in a compact matrix while one connected editor configures
|
||
the selected cell. The editor uses two lanes when its container has enough
|
||
width. Equipment identity and base values occupy the first lane; allocations,
|
||
rolls, Talents, and upgrades occupy the second. The lanes stack when either
|
||
would become too narrow. The full-width Specialization and Focus cell is the
|
||
root choice. Its three supplied abilities appear directly below it, followed by
|
||
two weapons, six gear positions, and one full-width OS Protocol.
|
||
|
||
Matrix cells show the slot and equipped item at rest. The selected cell reveals
|
||
its compact Talent, Attribute, Brand Set, or Skill Chip summary. This
|
||
progressive disclosure keeps the matrix scannable without replacing configured
|
||
choices with counts. Selecting an ability opens its three attached Skill Chip
|
||
positions. Selecting equipment opens the searchable real-data catalog and its
|
||
compatible configuration controls. Large Talent pools show the selected Talent
|
||
at rest and open their search grid through an explicit Change action. Do not
|
||
display a prototype option that the current loadout schema cannot save.
|
||
|
||
Builder cells use one leading icon track. Specializations, abilities, Skill
|
||
Chips, and OS Protocols use registered artwork; weapons and gear use static
|
||
category or slot fallbacks when no item artwork exists. Skill Chip slots keep
|
||
the icon beside the set name and quality so empty and configured slots share one
|
||
scan path. Visible builder labels stay short; full validation text remains
|
||
available through the cell's accessible name or title.
|
||
|
||
Each equipped gear or weapon Talent exposes two adjacent icon choices for Tier I
|
||
and Tier II. Both choices reuse the Talent artwork; Tier II applies a restrained
|
||
warm recolor so players can distinguish the pair before reading the labels.
|
||
Every tile retains `T1` or `T2`, its full tier name, and selected or unavailable
|
||
text. Disable Tier II when the canonical Talent has no authored Tier II data.
|
||
Weapon equipment tier and Talent tier are independent selections.
|
||
|
||
Equipment readiness belongs at the point of resolution. Mark an incomplete
|
||
matrix cell with a compact red text indicator and status rail, then let the cell
|
||
open the editor that resolves it. The live totals rail summarizes deterministic
|
||
equipped-item totals. Separate panels label conditional Talent outcomes, weapon
|
||
and Skill DPS, encounter assumptions, activation profiles, rotations, and
|
||
simulation as `COMING SOON`; they do not report calculation-profile blockers as
|
||
current player errors.
|
||
|
||
The builder uses two primary workbench columns on wide screens: the compact
|
||
matrix and the two-lane editor. The live summary spans both columns below them.
|
||
Narrow screens stack the matrix, editor, and summary. Every grid track and
|
||
editor child must accept content shrinkage. At 560px and below, stack Attribute
|
||
picker/value pairs and section headings; keep the command actions in two equal
|
||
columns. Validation markers use short visible labels while their full messages
|
||
remain available to assistive technology and pointer users.
|
||
|
||
Use `--shd-builder-canvas` for recessed equipment fields. Use
|
||
`--shd-builder-selection` with `--shd-builder-selection-border` for the selected
|
||
cell. Preserve button semantics, `aria-pressed`, focus-visible outlines, pressed
|
||
feedback, and textual readiness states. On mobile, stack the matrix, editor, and
|
||
live results in that order.
|
||
|
||
The command header contains the required build name, local and account save
|
||
actions, account visibility, and optional sharing notes. Sharing notes include a
|
||
short strengths summary and a Markdown usage guide. Persist them separately from
|
||
the validated loadout payload and render them on the shared build page.
|
||
|
||
### Prelaunch network shell
|
||
|
||
Use the standalone prelaunch shell for `/coming-soon`. It replaces the global
|
||
application shell while the public launch gate is active, so visitors see one
|
||
clear deployment message instead of navigation into gated sections. Keep the
|
||
SHD.build mark, a visible network-state block, one primary access action, the
|
||
Discord community action, the deployment manifest, and legal links. Signed-out
|
||
visitors receive `AGENT SIGN IN`; an authenticated operator previewing the page
|
||
receives `ENTER FULL SITE`.
|
||
|
||
The desktop composition pairs the launch statement with a technical network
|
||
visual. Use the shared grid background, square borders, restrained orange
|
||
emphasis, and telemetry labels. Orange identifies the primary action and active
|
||
signal paths. Green may reinforce a staged or available state; red may reinforce
|
||
an unavailable channel. Every state also needs a text label.
|
||
|
||
The deployment manifest lists News, Database, Builds, Guides, and Builder with
|
||
plain-language descriptions. A visitor who follows a disabled-section URL sees
|
||
the affected section name in a status notice. The page must state whether new
|
||
agent registration is open without implying that sign-in for existing accounts
|
||
has closed. The manifest uses the saved section controls as its source of truth
|
||
and marks unavailable sections in text. An authenticated preview follows the
|
||
same availability states.
|
||
|
||
At widths below 900px, stack the launch statement above the network visual and
|
||
collapse the manifest to one column as space requires. Preserve 44px action
|
||
targets and keep status text within the viewport. Reduce the radar sweep and
|
||
other ambient motion under `prefers-reduced-motion`; retain the static rings,
|
||
nodes, and labels.
|
||
|
||
ISAC Site Controls use collapsible command panels for Launch Gate, Account
|
||
Creation, Public Sections, moderation policy groups, thresholds, and the term
|
||
registry. Build these panels with `CollapsibleSection`. The disclosure button
|
||
must expose `aria-expanded` and `aria-controls`, retain its title and textual
|
||
status while closed, show a focus-visible outline, and provide at least a
|
||
44-pixel touch target. Keep panel content in the document and hide it while
|
||
closed so draft form state survives expansion changes. Disable motion under
|
||
`prefers-reduced-motion`.
|
||
|
||
Each command panel owns its save action, validation feedback, pending state, and
|
||
success notice. Do not place a page-wide review or save banner between panels.
|
||
Disable a panel's save button until that panel differs from saved state. Saving
|
||
one panel must update only its fields, retain the panel's open state, and leave
|
||
unsaved drafts in other panels unchanged. Keep `PREVIEW PAGE` inside the Launch
|
||
Gate save row so authenticated operators can inspect the promotional page
|
||
without ending their session. Operators need text for enabled, disabled,
|
||
coming-soon, and public states; color supports those labels.
|
||
|
||
The Launch Gate controls signed-out entry to the application. Public Section
|
||
controls apply to everyone. When an operator disables News, Database, Builds,
|
||
Guides, or Builder, remove that destination from global navigation for signed-in
|
||
and signed-out users and block its route family on the server. The promotional
|
||
page identifies a disabled destination when a user follows an old bookmark or
|
||
direct URL. Do not present authentication as a way around a disabled section.
|
||
|
||
### Agent and authentication surfaces
|
||
|
||
- The canonical signed-in account surface is the owner’s public Agent profile at
|
||
`/agents/{slug}`. `/account` is a compatibility route that redirects there;
|
||
the full notification inbox remains at `/account/notifications`.
|
||
- Owners see the same dossier and conversation that visitors see, plus inline
|
||
bio editing and a compact Account Control widget in the right rail. Do not
|
||
create a separate profile-editing dashboard or remove community context while
|
||
the owner manages their profile.
|
||
- Dense account consoles use a tabbed control surface for profile, credentials,
|
||
linked identities, and account lifecycle actions. Only one panel is shown at a
|
||
time; validation failures reopen the panel containing the failed action.
|
||
Closely related mutually exclusive workflows, such as selecting a preset
|
||
portrait or uploading a custom portrait, use a compact secondary tab row. Tabs
|
||
retain native button semantics plus tablist, tab, and tabpanel roles, textual
|
||
selected state, keyboard focus, and pressed feedback.
|
||
- Account Access uses a secondary method navigation for passkeys, verified
|
||
email, local password fallback, and linked identity providers. Each tab shows
|
||
a compact configured-method count and routes failed actions back to the
|
||
relevant panel. External identity connections live inside Access rather than
|
||
competing with it as a top-level account domain.
|
||
- Future external providers may appear as non-interactive planned rows so the
|
||
intended identity architecture is visible before credentials are configured.
|
||
Placeholders must be visually subdued, explicitly labeled `PLANNED`, and must
|
||
not imitate enabled buttons. Provider-compliant assets and controls replace
|
||
these rows only when the corresponding OAuth application is implemented.
|
||
- Provider unlinking does not assume that a password exists. The unlink control
|
||
is the provider card’s `LINKED` status badge. Hover and keyboard focus turn it
|
||
red and replace the label with `UNLINK`; activation replaces the full card
|
||
surface with an explicit Cancel / Confirm Unlink decision. Confirmation uses
|
||
the square SHD primary action with the orange action accent, while Cancel
|
||
remains a dark outlined secondary control. The authenticated session plus this
|
||
deliberate second action authorizes the request; the shared server-side
|
||
last-method guard remains authoritative. Future provider cards reuse this
|
||
pattern rather than adding provider-specific credential prompts.
|
||
- Authentication pages use a split frame: contextual SHD network information on
|
||
the left and the actionable secure-access console on the right.
|
||
- OAuth providers appear as connection nodes with a recognizable provider color;
|
||
SHD orange remains reserved for the primary local action and navigation.
|
||
- Authentication prioritizes passkeys, followed by one-time email magic links.
|
||
Discord remains a prominent provider option, while username/password is an
|
||
explicitly labeled optional fallback in a collapsed control. Passkey controls
|
||
name the platform interaction rather than exposing WebAuthn terminology.
|
||
- Verified email identities and registered passkeys appear as compact method
|
||
rows in Account Access. Every method displays its verification or device
|
||
state, registration date where useful, and protected removal behavior that
|
||
prevents an agent from deleting their last usable sign-in method.
|
||
- Local username and password are one optional authentication method, separate
|
||
from the public display name and the immutable internal account identifier.
|
||
Agents may remove both local credentials together after adding another method,
|
||
and may restore them later with a new unique login username and password.
|
||
- The “at least one sign-in method” rule is a server-side invariant shared by
|
||
self-service and ISAC actions. Passkeys, verified magic-link email, Discord,
|
||
and a complete local username/password pair each count as usable methods.
|
||
Controls may disable unsafe removal for clarity, but server validation remains
|
||
authoritative. Intentional soft account deletion is the sole exception.
|
||
- Linked identity nodes show provider display name, account handle or stable ID,
|
||
and an explicit textual `LINKED` state. Unlink controls sit beneath the node,
|
||
require credential confirmation, and remain disabled with an explanation when
|
||
unlinking would remove the user's only sign-in method.
|
||
- ISAC user dossiers reuse the same linked-identity node. Administrative
|
||
unlinking requires a scoped identity-management capability, produces an audit
|
||
event, and must never remove the user's only available sign-in method.
|
||
- On small screens, the split frame becomes one column. Show the public dossier
|
||
and archives first, followed by Account Control, notifications, and Recent
|
||
Discussion. Place Profile Messages at the bottom. Give owners a mobile-only
|
||
header link to Account Control.
|
||
- Public display names and private login usernames are distinct. Display names
|
||
support normalized Unicode and relaxed visible characters. They are unique
|
||
under the product's normalized identity key and generate readable,
|
||
collision-safe public-profile slugs. New accounts receive the next available
|
||
`Agent N` placeholder until the owner chooses a name. Login usernames remain
|
||
unique, ASCII-only credentials and must never appear on public-facing
|
||
community surfaces. Authorized ISAC user operations may show both.
|
||
|
||
### Public Agent profiles
|
||
|
||
Public Agent profiles are community dossiers. The owner view extends the same
|
||
page with account controls without changing its public hierarchy. Lead with the
|
||
shared `AgentIdentityLink` in its large state: circular portrait, display name,
|
||
and assigned role badges. Place role badges to the right of the display name on
|
||
desktop and below the name on mobile. Show role names only, in alphabetical
|
||
order, and omit the list when the Agent has no assigned roles. Badges use the
|
||
shared raised surface, explicit role text, and a small orange diamond; they wrap
|
||
without truncating long or multiple role names. Never expose role descriptions,
|
||
permissions, direct grants, or access scopes on public profiles. The owner
|
||
header contains the visibility switch, its information control, and a
|
||
mobile-only Account Control link. Present the primary identity and its actions
|
||
directly on the page canvas without a card surface, border, or decorative accent
|
||
rule. Give the identity and actions content-sized responsive tracks so long
|
||
names, multiple roles, and mobile actions cannot overlap the public content
|
||
totals. Keep those totals in a compact telemetry strip below the identity
|
||
header. Use four columns on desktop and two columns on mobile. Place the field
|
||
bio in the primary column and keep its mobile Edit Bio action compact within the
|
||
section header. Put Public Builds and Published Guides side by side directly
|
||
beneath the bio; stack them on narrow screens. Their cards stay within their own
|
||
half of the primary column. Profile Messages follow the archive pair within the
|
||
same column and must not inherit height from the right rail.
|
||
|
||
Recent Discussion occupies the narrower activity rail. Owner-only Account
|
||
Control and notification-preview widgets appear above it. The profile preview
|
||
shows unread notifications only; the full inbox retains notification history.
|
||
Recent-discussion entries use compact destination cards because each entry links
|
||
to content elsewhere on the site. Show only the discussion type, destination
|
||
title, comment date, and open action; do not repeat the message body in this
|
||
rail. Reset nested card headers to content height and align the destination
|
||
identity with its date; do not inherit the application header's fixed height or
|
||
surface treatment. Profile messages continue directly beneath the biography in
|
||
the primary column so the conversation begins without dead space.
|
||
|
||
Use `AgentIdentityLink` for author attribution on builds, guides, comments, and
|
||
other community records. Its compact and default states combine the circular
|
||
portrait, public display name, assigned public role badges, and optional
|
||
contextual metadata. Role badges remain beside the display name in comment
|
||
headers and other author attributions; an empty role list renders no badge. The
|
||
display name supplies the link affordance through its hover and focus-visible
|
||
states; do not add a trailing arrow. Use the primary orange token for the
|
||
portrait border, with a two-pixel edge that remains legible against the page
|
||
canvas. The default author portrait is 44 pixels; compact identities may use 30
|
||
pixels. The portrait remains circular at every size; selectors may use square
|
||
tactical thumbnails only where the avatar rules explicitly allow them.
|
||
|
||
Public-profile links use the stored readable slug, URL-encoded as one path
|
||
segment. A display-name change updates the canonical slug. Legacy UUID routes
|
||
remain valid and redirect to the canonical address; UUIDs remain the internal
|
||
identity for mutations, relationships, and audit evidence.
|
||
|
||
Public biographies use the shared `MarkdownEditor` and `MarkdownContent` pair.
|
||
The editor supplies formatting controls, a remaining-character count, concise
|
||
help, and a readable editorial typeface. Profile messages and replies use the
|
||
compact `CommentComposer`: one textarea, a Markdown notice, a character count,
|
||
and submit or cancel actions. Rendered Markdown supports headings, lists,
|
||
quotes, links, bold, italics, and inline code. Load the required editorial font
|
||
weights and italic face because the global type system disables synthetic font
|
||
styles. Raw HTML is escaped.
|
||
|
||
Guides and News use the shared structured article composer rather than the
|
||
compact Markdown editor. The composer treats the article as an editorial work
|
||
surface. The full-width title and deck match the published lede, while the
|
||
readable canvas stays near 76 characters. A publication bar above the canvas
|
||
groups visibility, News channel, publication state, and the primary action. The
|
||
sticky right inspector contains cover media, Guide tags, moderation context, and
|
||
deletion without narrowing the headline preview. The sticky toolbar uses native
|
||
buttons for paragraph, H2, H3, bold, italic, inline code, links, lists, quotes,
|
||
dividers, images, Build embeds, undo, and redo. On narrow screens, the 44-pixel
|
||
toolbar scrolls horizontally, followed by the publication bar and inspector in
|
||
document order.
|
||
|
||
Persist the versioned Tiptap JSON document, never generated editor HTML. The
|
||
server accepts only documented nodes, marks, attributes, HTTP or HTTPS links,
|
||
bounded depth, and bounded text. `ArticleContent` renders validated nodes with
|
||
Svelte elements. Inline article images require alternative text and may include
|
||
a caption. The reading page uses Source Serif 4 for prose and Barlow for
|
||
headings, metadata, controls, and embedded operational data.
|
||
|
||
`BuildEmbed` is the reusable article representation for a saved Build. A Guide
|
||
may contain several Build blocks, and a Build may appear in several Guides. Each
|
||
published revision stores the stable Build ID and a bounded display snapshot.
|
||
The component renders a connected weapon and gear matrix instead of an
|
||
interactive Builder. An author-owned private or unlisted Build displays as
|
||
`AUTHOR-SHARED`; the Guide makes that snapshot public without changing the Build
|
||
page visibility. A Build owned by another Agent displays only while the source
|
||
remains public.
|
||
|
||
Guide discovery separates three Community Oversight decisions. Pins form an
|
||
ordered group above the default feed, Featured Guides occupy a dedicated
|
||
editorial group, and Recommended Guides carry a textual badge and filter. Search
|
||
relevance is not overridden by curation. Guide cards pair a cover or
|
||
field-manual fallback with title, deck, author, publication date, tags, and the
|
||
rating count. Unlisted and private articles never enter discovery or search.
|
||
Official Ubisoft News cards use the validated source thumbnail through the
|
||
same-origin image proxy and link their cover and headline to the canonical
|
||
Ubisoft article. The `BY UBISOFT` metadata identifies the external destination
|
||
before activation. Internal News and all Guides continue to use SHD.build
|
||
article routes.
|
||
|
||
Profile conversations begin with a collapsed `LEAVE A MESSAGE` action. A reply
|
||
opens the same editor beneath the selected message, and only one editor remains
|
||
open. Comments sit on the page canvas without cards, section surfaces, or
|
||
detached author headers. Align each body and action row with the username rather
|
||
than the avatar gutter. Keep Reply visible below the message. Place Follow or
|
||
Unfollow, Report, and the author-only Remove action in a shared ellipsis menu
|
||
beside Reply. The menu uses a 44-pixel trigger, returns focus when closed,
|
||
supports Escape and directional-key navigation, and becomes a fixed bottom panel
|
||
on narrow screens. Keep destructive actions neutral at rest and use the danger
|
||
color on hover or keyboard focus. Render conversations in depth-first reading
|
||
order: newest root conversations first and each branch oldest-first. Use
|
||
one-pixel guide lines and restrained indentation for replies, then cap visual
|
||
indentation on narrow screens while retaining the logical parent chain. If an
|
||
author or moderator removes a message that has replies, show a bodyless
|
||
`MESSAGE REMOVED` placeholder so readers can follow the remaining conversation.
|
||
Following applies to the top-level conversation and sends inbox notifications
|
||
for visible descendant replies, excluding the reply author and any recipient
|
||
already receiving the direct-reply notification. Send reply notifications to the
|
||
direct parent author and link to the specific reply. Recent-discussion links
|
||
target the exact comment anchor instead of the containing profile or content
|
||
page.
|
||
|
||
Public user-generated content uses the shared `ContentReport` control when the
|
||
viewer is authenticated and does not own the content. Keep the control visually
|
||
secondary to reading and reply actions. Its disclosure names the concern,
|
||
accepts optional bounded context, and states that a report requests human review
|
||
without removing content immediately. On narrow screens, present the report form
|
||
as a fixed bottom panel with full-width touch controls.
|
||
|
||
Submission forms for public user-generated text and custom images use the shared
|
||
`ModerationDisclosure` notice. Place it after the input and before validation or
|
||
submission controls. The always-visible notice states that automated safety
|
||
review may occur and links to the Terms & Privacy section for the details. Do
|
||
not hide this disclosure in a hover-only tooltip.
|
||
|
||
Automated moderation is exception-based. Clean content publishes without an
|
||
Oversight task when policy permits. Flagged comments remain hidden with an
|
||
explicit pending state; flagged long-form edits leave the last approved version
|
||
public. Flagged custom avatars use the default avatar publicly until approval.
|
||
Community Oversight shows automated evidence and Agent reports in one pending
|
||
queue, but labels their sources separately. Human approval, rejection, removal,
|
||
and report dismissal require a reason and confirmation.
|
||
|
||
The Site Controls term registry supports single-rule editing and an inline bulk
|
||
editor. The bulk editor accepts pasted lists, applies one effect and scope set
|
||
to the batch, previews the unique-entry count, and states the 250-rule limit.
|
||
Keep it inline because operators need the registry for context. Show exact-word
|
||
behavior beside the textarea, preserve pasted values after validation errors,
|
||
and clear the textarea while keeping the editor open after a successful import.
|
||
Search the registry on the server across term text, normalized text, rule type,
|
||
match mode, and operational note. Use the shared pagination rail with namespaced
|
||
URL parameters and 25 rows by default. Search applies before pagination.
|
||
Distinguish an empty registry from a search with no matches. The registry
|
||
toolbar, editors, search, and pagination stay inside the term disclosure. Only
|
||
HTTP and HTTPS links are active; rendered links open separately with UGC,
|
||
nofollow, and opener-isolation attributes. `MarkdownContent` must receive HTML
|
||
from the server renderer, never raw user input or client-rendered Markdown.
|
||
|
||
Rendered biography copy uses the editorial typeface and a restrained reading
|
||
measure. Compact comment rendering uses the same hierarchy at a denser scale.
|
||
Comment cards identify the author and date before the message. Activity cards
|
||
identify the content type and title, render a useful excerpt, and provide a
|
||
specific action such as `OPEN DISCUSSION`. Empty states state which public
|
||
record is absent without implying an error.
|
||
|
||
Profile visibility is an explicit public or hidden account setting. A hidden
|
||
profile is excluded from public discovery and cannot receive new profile
|
||
messages. Hiding it does not remove the Agent's display name or portrait from
|
||
public builds, guides, or comments they authored. Put the compact textual
|
||
`PUBLIC` or `HIDDEN` switch in the owner’s identity header and explain the
|
||
consequence in an adjacent information popover. Display-name restrictions use
|
||
the same popover pattern instead of persistent instructional copy.
|
||
|
||
Community forms use `PendingForm` to block duplicate submissions. Pending
|
||
actions retain their label context, validation errors preserve entered text, and
|
||
success or error feedback appears beside the affected form. All editor, link,
|
||
and button controls require the shared orange focus-visible treatment. Message
|
||
removal is a two-step, in-card confirmation: the first action reveals a red
|
||
danger panel, then separate Cancel and Confirm Remove actions complete or
|
||
abandon the request. Only an authorized author receives the removal control.
|
||
|
||
Below 1000px, move profile communications beneath the primary content and stop
|
||
using the sticky position. Below 650px, stack the identity header, telemetry,
|
||
section headers, and content cards into one column. Expand owner actions,
|
||
submission controls, and deletion controls to 44px touch targets. Keep the
|
||
Cancel and Confirm Remove actions side by side when both labels fit. Respect
|
||
`prefers-reduced-motion` without removing static hover, focus, pending, success,
|
||
error, or danger indicators.
|
||
|
||
### Third-party identity buttons
|
||
|
||
- Follow the identity provider's current official brand and sign-in guidelines.
|
||
- Use official, unmodified assets downloaded from the provider's brand
|
||
resources.
|
||
- Discord sign-in uses the official white Discord symbol on Blurple `#5865F2`
|
||
with the explicit label “Continue with Discord.”
|
||
- Discord account connection controls use the same official symbol and Blurple
|
||
treatment with the explicit label “Link Discord.”
|
||
- Sign-in pages group external providers into a compact, equal-weight provider
|
||
rail. Keep a short visible provider name beneath each mark; accessible names
|
||
and hover text are supplementary and do not replace required brand wording.
|
||
- Google uses its standard multicolor G on a white icon field, Apple uses a
|
||
white Apple mark on black, Discord uses its unmodified white symbol on
|
||
Blurple, and Steam uses its white linked-circle mark on Steam navy.
|
||
- Providers that are not configured are disabled, desaturated, and marked
|
||
`PLANNED`; they must not navigate, submit, or imply availability through
|
||
styling.
|
||
- When each provider is implemented, replace its placeholder with the
|
||
provider-rendered control or current pre-approved sign-in artwork where the
|
||
provider requires it. In particular, use Google Identity Services or its
|
||
approved icon-mode asset and Steam's published sign-in image.
|
||
- Preserve the provider's required clearspace, logo proportions, approved color,
|
||
readable contrast, and text/logo alignment even when the surrounding surface
|
||
follows the SHD theme.
|
||
- Provider buttons still require SHD.build's focus-visible, pressed, pending,
|
||
and duplicate-interaction protection where those states do not conflict with
|
||
the provider's branding requirements.
|
||
- Authentication uses one unified access screen rather than separate sign-in and
|
||
registration destinations. Verified email and first-time OAuth identities may
|
||
create an account; returning identities sign into the matching account.
|
||
- With account creation disabled, keep returning-agent methods available, hide
|
||
the password `CREATE ACCOUNT` mode, and show a concise registration-state
|
||
notice. Provider and email controls must explain that unknown identities
|
||
cannot create an account without suggesting that existing identities lost
|
||
access.
|
||
- Password access uses an explicit `SIGN IN` / `CREATE ACCOUNT` mode switch
|
||
inside the fallback panel. Account creation separates the public display name
|
||
from the private ASCII login username.
|
||
- Passkeys are a returning-user method on this screen. New agents first
|
||
establish an account through verified email, OAuth, or local credentials, then
|
||
enroll a passkey from Account Access.
|
||
|
||
### Footer and legal surfaces
|
||
|
||
- Every routed page ends with the global SHD footer containing Terms & Privacy,
|
||
data-retention access, and the unofficial Ubisoft fan-site disclaimer.
|
||
- Legal pages retain the command-console visual language but prioritize readable
|
||
serif body copy, anchored sections, and restrained line length.
|
||
- Login security metadata is operationally visible in ISAC for 30 days. After
|
||
that period, IP, user-agent, normalized client/device fields, and credential
|
||
references and proxy-supplied approximate location are scrubbed while
|
||
non-sensitive event facts, categorical risk flags, and session outcomes may
|
||
remain.
|
||
|
||
### Admin dashboard
|
||
|
||
- Use `admin-page`, `admin-command`, `admin-dashboard`, `admin-sidebar`, and
|
||
`admin-content`.
|
||
- The administrative system is named ISAC. Separate navigation into explicit
|
||
operational domains such as User Operations and Data Management; visibility
|
||
must reflect server-provided capabilities.
|
||
- In the ISAC rail, operational-domain headers are compact disclosure bars, not
|
||
module destinations. Give them a stronger surface, bold uppercase text, a
|
||
count, and a short leading status rail that turns orange while expanded.
|
||
Module destinations sit on the darker recessed surface below, use sentence
|
||
case and an additional left inset, and reserve the full orange rail for the
|
||
current module. Preserve this hierarchy when the rail becomes a mobile grid.
|
||
- ISAC module navigation uses complete, game-facing names such as `Weapons`,
|
||
`Talents`, and `OS Protocols`. Do not expose internal abbreviations such as
|
||
`WPN`, `TLNT`, or `OSPR`. Canonical game icons may supplement visible labels
|
||
inside module content and editor controls, but the navigation rail must not
|
||
invent iconography merely to replace clear language.
|
||
- User Operations shows every supported authentication method as operational
|
||
metadata: local credentials, verified email, passkeys, Discord, and planned
|
||
providers. Identity-removal controls require `users.identities`, create audit
|
||
records, and preserve at least one remaining sign-in method.
|
||
- The Agent Registry prioritizes assigned roles over authentication-method
|
||
summaries. Authentication details belong in the individual agent dossier.
|
||
- ISAC authentication-method removal is always a two-step interaction contained
|
||
within the affected method row. The confirmation state explains the impact and
|
||
provides explicit Cancel and orange Confirm actions before submission.
|
||
- Agent dossiers consolidate operational controls into full-width tabs for Roles
|
||
& Permissions, Authentication, and Moderation. Keep dense controls in their
|
||
relevant tab instead of allowing one dashboard column to grow far beyond
|
||
adjacent content.
|
||
- Avatar removal uses the same in-card, two-step confirmation interaction as
|
||
authentication-method removal.
|
||
- Role and permission changes require a modal review step that summarizes the
|
||
complete selected role and direct-permission sets. Only the modal's orange
|
||
Confirm action submits the assignment.
|
||
- Access-review summaries are diffs: retained assignments use a neutral `KEEP`
|
||
state, additions use green `ADD`, and removals use red `REMOVE` with struck
|
||
assignment text. Added and removed items appear together in their respective
|
||
role or direct-permission column.
|
||
- Login, build/guide, and comment histories are independent support registries.
|
||
Each provides context-appropriate filters and namespaced pagination controls
|
||
so changing one history page does not reset the others.
|
||
- Each module starts with `module-toolbar`, followed by `module-kpis`.
|
||
- Editors use `dashboard-editor`. New-record editors appear before the affected
|
||
table. Editing an existing record expands the same editor directly beneath its
|
||
selected row, which gains an orange selection rail and an explicit expanded
|
||
relationship for assistive technology. Inline editors stay aligned to the
|
||
visible registry viewport when the table scrolls horizontally. A short clipped
|
||
reveal confirms the expansion; reduced-motion preferences remove that
|
||
animation.
|
||
- Optional record descriptions use a full-width narrative field beneath the
|
||
identity controls. Preserve the same full-width placement in Oversight
|
||
before/after previews so reviewers can compare meaning without reading raw
|
||
proposal data.
|
||
- Data collections use `dashboard-table`, `dashboard-row`, and `table-heading`.
|
||
- Keep tables dense and horizontally scrollable rather than wrapping columns
|
||
unpredictably.
|
||
- User dossiers pair access controls and moderation in a two-column console,
|
||
followed by compact login and content-history streams. Restriction state must
|
||
be textual and use the danger color; inactivity remains a separate activity
|
||
classification rather than a punishment state.
|
||
- Role names describe durable organizational responsibility. `Admin` is the
|
||
unrestricted administrative role; `Community Oversight` is reserved for
|
||
community content moderation and does not imply ISAC access. Operational ISAC
|
||
access is delegated separately through scoped roles and permissions.
|
||
- Roles is a separate User Operations registry. Role definitions compose
|
||
discrete capabilities through a dense permission catalogue with an explicit
|
||
selected count and textual `GRANTED` / `NOT GRANTED` states. The core Admin
|
||
role is deletion-protected because it provides the system's unrestricted
|
||
access mechanism. Full administrators may edit every role and delete seeded
|
||
operational roles; deletion records a persistent tombstone so migrations do
|
||
not recreate the role. Delegated access managers may edit seeded operational
|
||
roles but may delete only custom roles. Every deletion requires an exact-name
|
||
confirmation that states how many agents will immediately lose the role. Keep
|
||
Delete separated from Edit and use the danger treatment only inside this
|
||
confirmed path. Delegated access managers must never be able to grant
|
||
`system.admin`; both option visibility and server-side validation enforce this
|
||
boundary. Role mutations are recorded in the audit log with their previous and
|
||
resulting permission and assignment evidence.
|
||
- Audit History belongs to a separate `SYSTEM OVERSIGHT` navigation domain.
|
||
Audit records are append-only operational evidence and show the operator,
|
||
categorical action, target identifier, timestamp, and expandable before/after
|
||
JSON snapshots. Search and category/action filters run before pagination. The
|
||
Auditor role grants read-only `audit.view` access plus entry to ISAC; audit
|
||
visibility never implies mutation, user-management, or game-data access.
|
||
- Supported audit events may expose a permissioned compensating-action control.
|
||
Reversion uses a danger-styled `ATTEMPT REVERT` entry action followed by a
|
||
modal that explains the original action, operator, target, and conflict
|
||
checks. The orange Confirm action is the only submission path. ISAC compares
|
||
current state with the original event’s after-snapshot before restoring the
|
||
before-snapshot; newer work blocks the operation. Successful reversions append
|
||
a new `audit.reverted` event and never alter the original history.
|
||
`audit.view` remains read-only; `audit.revert` is independently assigned.
|
||
- System Metrics is the second read-only System Oversight surface. It uses a
|
||
compact KPI row for headline process health and a two-column grid of dense
|
||
runtime, host, database, and service-volume panels. Refresh is explicit and
|
||
duplicate-safe; optional auto-refresh is visibly selected and uses a
|
||
restrained ten-second interval. Metrics must not expose environment values,
|
||
credentials, full filesystem paths, or other deployment secrets. The
|
||
`metrics.view` permission is independent of mutation access and is included in
|
||
the read-only Auditor role. External-service capacity reuses the same metric
|
||
panel: show distinct provider pools, the last authoritative check, configured
|
||
alert thresholds, and explicit `OK`, `WARNING`, `CRITICAL`, or unavailable
|
||
text. Green, orange, and red reinforce these states but never replace their
|
||
labels.
|
||
- Account deletion uses a collapsed danger zone, explicit identity confirmation,
|
||
and plain-language retention guidance. Soft-deleted accounts retain authored
|
||
content under a deleted-agent identity while releasing credentials, usernames,
|
||
external identity links, sessions, roles, and permissions.
|
||
- Threshold-based set bonuses use compact `effect-band` groups. Each threshold
|
||
is displayed as a fixed piece-count marker followed by its mapped stat and
|
||
value, keeping progression readable in editors and table summaries.
|
||
- Multi-value compatibility fields use a dense `selection-grid` of checkbox rows
|
||
with a visible selected-count summary. Keep the entire row clickable and
|
||
preserve native checkbox semantics for keyboard and assistive-technology use.
|
||
- When compatibility is conditional on another field, show only valid choices,
|
||
clear stale selections when the controlling field changes, and state required
|
||
minimum selections in both the section label and validation feedback.
|
||
- Tiered records with shared structure use one shared selector and side-by-side
|
||
value columns rather than duplicating the entire editor. Template-driven copy
|
||
must show live previews for every tier and document its placeholder syntax.
|
||
|
||
### Forms
|
||
|
||
- Labels are uppercase and letter-spaced.
|
||
- Inputs use dark surfaces, one-pixel borders, and clear disabled styling.
|
||
- Text selection uses the SHD orange selection token with dark contrasting text;
|
||
never rely on the browser's white or platform-blue highlight. Focused text,
|
||
number, search, select, and textarea controls use a one-pixel orange border,
|
||
while keyboard `focus-visible` adds a restrained one-pixel external orange
|
||
ring with a one-pixel offset. Do not stack inset accent edges with this focus
|
||
treatment. Carets and native checkbox, radio, and range accents use orange.
|
||
Browser-autofilled fields retain the dark SHD surface and light text.
|
||
- Related min/max fields remain visually paired.
|
||
- Small mutually exclusive option sets use a compact segmented radio control,
|
||
even when visually presented like selectable checkbox cells. Include an
|
||
explicit “None” option when the field is optional.
|
||
- Primary save actions sit at the lower right. Cancel is secondary.
|
||
- Destructive/archive actions are visually separated from save actions.
|
||
- Server validation returns errors for specific editor areas. Show a focused
|
||
error summary with links to each affected area, mark invalid native controls
|
||
with `aria-invalid`, and place the error text beside the relevant field or
|
||
section. Preserve all entered values. Color supports the text and border
|
||
treatment; it never carries the error state alone.
|
||
|
||
## Interaction rules
|
||
|
||
- Every interactive element needs a pointer cursor unless disabled.
|
||
- Buttons have hover, pressed, focus-visible, pending, and disabled states.
|
||
- Forms that send requests should use `PendingForm.svelte` or equivalent
|
||
enhancement to prevent duplicate submissions.
|
||
- Pending buttons use `aria-busy="true"` and remain disabled until the request
|
||
completes.
|
||
- Respect `prefers-reduced-motion`.
|
||
|
||
## Color semantics
|
||
|
||
- Orange: primary action, current location, selected operational value.
|
||
- Green: online, active, configured, or successful.
|
||
- Red: destructive action, error, or offensive classification when context
|
||
requires it.
|
||
- Blue: defensive or informational classification.
|
||
- Gray: inactive, archived, unavailable, or supporting metadata.
|
||
|
||
Do not communicate state by color alone; include a label, icon, or pattern.
|
||
|
||
## Responsive behavior
|
||
|
||
- Collapse the dashboard sidebar into a two-column module grid below 900px.
|
||
- KPI tiles become two columns on small screens.
|
||
- Tier editors stack vertically on tablets.
|
||
- Tables retain a useful minimum width and scroll horizontally.
|
||
- Primary and secondary toolbar actions may expand equally on narrow screens.
|
||
|
||
## Adding a new admin module
|
||
|
||
1. Add the route beneath `src/routes/isac`.
|
||
2. Register it in the admin layout navigation.
|
||
3. Start with the module toolbar and KPI row.
|
||
4. Reuse dashboard editor and table classes.
|
||
5. Use the shared tokens instead of introducing near-duplicate colors.
|
||
6. Verify keyboard focus, pending behavior, empty states, mobile layout, and
|
||
archived data behavior.
|
||
|
||
Document a new interface pattern here when you introduce it.
|
||
|
||
## Design-system governance
|
||
|
||
Update this document and the shared implementation with each significant visual
|
||
or interaction change. A change qualifies when it introduces or revises a
|
||
reusable token, component pattern, layout, responsive rule, accessibility
|
||
behavior, motion behavior, or state convention.
|
||
|
||
Small alignment corrections and isolated visual bug fixes need no documentation
|
||
change unless they establish a reusable rule.
|
||
|
||
Repository agents and contributors should follow the maintenance checklist in
|
||
`AGENTS.md`.
|
||
|
||
### Agent avatars
|
||
|
||
Agent portraits use a circular crop in identity headers and square tactical
|
||
thumbnails in selectors. Account Control shows the current portrait first and
|
||
keeps preset and upload controls behind an explicit Edit Avatar action. Preset
|
||
choices appear in a compact four-column grid; the active choice uses the orange
|
||
action border and an explicit pressed state. Custom images are normalized
|
||
server-side to a metadata-free 256 × 256 WebP. Selectors must retain visible
|
||
hover, focus-visible, pressed, pending, and disabled states, and collapse
|
||
naturally with their containing account console. ISAC user dossiers show the
|
||
current portrait, distinguish preset and custom sources textually, and place
|
||
destructive custom-image removal behind the existing moderation permission and
|
||
pending-action pattern. Moderation actions use full-width engineered controls:
|
||
neutral outlined buttons for reversible identity changes and muted red controls
|
||
for destructive or restrictive changes. Every control must expose pointer,
|
||
hover, focus-visible, pressed, disabled, and inline pending-spinner states;
|
||
adjacent navigation links use the same height, typography, and interaction
|
||
motion.
|
||
|
||
### Weapon definition editor
|
||
|
||
Complex progression definitions use a stacked control-surface editor: identity
|
||
and fixed values first, then parallel tier cards, mutually exclusive talent
|
||
pools, and the augmentation sequence. Tier cards retain identical row ordering
|
||
so values can be compared horizontally on wide screens and stack without
|
||
changing meaning on narrow screens. System-derived augment steps appear as
|
||
read-only numbered cells; editable effects use the shared attribute/value row
|
||
pattern. Exotic is a status layered onto a weapon family, never a replacement
|
||
for the family classification. Exotic definitions add a dedicated exotic-only
|
||
talent after the two standard talent pools; their sixth augmentation cell
|
||
communicates that this talent advances to Tier II. The exotic talent is authored
|
||
in the Talent Registry under the `Exotic Weapon` category. The weapon editor
|
||
uses the shared searchable assignment pattern to reference one registered exotic
|
||
talent. Each option states whether another weapon owns it and whether
|
||
contributors have documented Tier II. Assigned talents remain visible but
|
||
unavailable to other weapon records. The selected talent stays removable from
|
||
its current weapon.
|
||
|
||
The Talent Registry owns the exotic talent name, icon, description template,
|
||
Tier previews, and mechanic program. Its explicit Tier II documentation choice
|
||
uses `DOCUMENTED` and `NOT YET DOCUMENTED`. Tier I remains required in both
|
||
states. The registry shows `NOT YET DOCUMENTED` in the Tier II column instead of
|
||
a zero value or synthesized description.
|
||
|
||
Place shared weapon-category bonuses above the weapon registry in one collapsed
|
||
profile console. Its six category buttons show the three inherited Attribute
|
||
values and open one category editor. The editor keeps Attribute identities fixed
|
||
and exposes only their positive numeric values. Saving closes the editor;
|
||
validation preserves its values and error state. Standard and Exotic weapons
|
||
inherit the profile for their underlying Shotgun, Rifle, MMR, AR, LMG, or SMG
|
||
category. Do not repeat these controls inside individual weapon editors.
|
||
|
||
Large relationship sets use the searchable assignment control instead of
|
||
checkbox walls. It keeps assigned records visible as removable chips, filters
|
||
available records by identity, renders at most thirty results at once, and
|
||
exposes counts for both assignments and matches. When records can share a name,
|
||
show the identity-defining qualifier below it in both selected chips and search
|
||
results. Attribute assignments use `UNIT · %`, `UNIT · s`, or `UNIT · FLAT`;
|
||
search and accessible names include that unit. Mutually exclusive pools pass
|
||
their assigned IDs to one another as exclusions so invalid combinations cannot
|
||
be selected. Keyboard focus, pressed state, empty results, and overflow remain
|
||
explicit. Where a relationship has a global slot invariant, filter each
|
||
assignment control at the data boundary instead of presenting cross-slot
|
||
choices. Weapon talents are classified once as Talent 1 / Top or Talent 2 /
|
||
Bottom in the talent registry; weapon editors only curate subsets from the
|
||
matching slot.
|
||
|
||
### Game-semantic iconography
|
||
|
||
Canonical game icons are registered in `src/lib/game-icons.ts` and rendered
|
||
through `GameIcon.svelte`; do not repeat asset paths in individual features. Use
|
||
damage icons beside Blast, Pierce, and Shredding classifications, and core
|
||
attribute icons beside Firepower, Toughness, and Engineering values. The same
|
||
registry reserves the Bulwark, Combat Medic, Demolitionist, Tech Operator,
|
||
Vanguard, Legendary, and SHD-ticket assets for controls or data that explicitly
|
||
represent those concepts. Do not use semantic icons as unrelated decoration.
|
||
|
||
Interactive icon choices retain a visible text label, square engineered cells,
|
||
orange selected state, and hover, pressed, and focus-visible feedback. Icons
|
||
that repeat an adjacent visible label are decorative with an empty alternative;
|
||
standalone icons expose the registry's human-readable label. Preserve each
|
||
asset's aspect ratio with `object-fit: contain` and scale through the shared
|
||
`.game-icon` class rather than modifying source artwork.
|
||
|
||
### Item quality
|
||
|
||
Item quality is a global semantic scale: Standard uses `--quality-standard`
|
||
green, Specialized uses `--quality-specialized` blue, Superior uses
|
||
`--quality-superior` purple, and High-end uses `--quality-high-end` yellow.
|
||
Apply the matching `.quality-*` utility wherever an item’s persisted quality is
|
||
shown. Registry labels use `.quality-chip` so quality remains explicit in text
|
||
and never depends on color alone. These colors identify item quality; orange
|
||
remains reserved for actions and current selection.
|
||
|
||
### OS Protocol editor
|
||
|
||
OS Protocol definitions separate shared secondary profiles from item-owned
|
||
progression. The twelve quality + attribute-type combinations are configured
|
||
once in a compact matrix and inherited by every matching protocol. Each profile
|
||
contains three fixed stat identities and editable values. Individual protocol
|
||
editors show the inherited profile read-only and store one unique primary stat
|
||
with a level-1 base value. That primary value scales linearly to exactly twice
|
||
its base at level 50.
|
||
|
||
Protocol identity forms stack the four-choice quality radio band above the
|
||
three-choice secondary-profile type band, with the protocol name occupying the
|
||
larger adjacent column. Quality choices use their global semantic color plus an
|
||
explicit text label and selected underline; profile types retain their
|
||
icon-backed labels. Both controls collapse below the name on narrow screens.
|
||
|
||
The shared secondary-profile matrix is collapsed by default because it is
|
||
configuration infrastructure rather than a frequent protocol-editing task. Its
|
||
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.
|
||
|
||
### Weapon and gear renders
|
||
|
||
Weapon and gear editors offer an optional item-render upload separate from the
|
||
icon system. Operators may save a definition without artwork, then add, replace,
|
||
or remove the render in a later edit. The upload accepts JPEG, PNG, WebP, and
|
||
AVIF up to 5 MiB. The server center-crops each upload to 1000 × 1000 and stores
|
||
it as WebP. It does not call remove.bg, trim the scene, or add transparency.
|
||
|
||
Show the current square render in the upload control and as a compact square
|
||
thumbnail before the item name in ISAC registry rows. Keep the image decorative
|
||
when the adjacent text identifies the item. The control states the crop and
|
||
format contract so contributors do not confuse a render with a transparent
|
||
game-data icon.
|
||
|
||
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.
|
||
|
||
Diamonds are both a progression preview and an explicit numeric state; expose
|
||
their upgrade number and `aria-pressed` state rather than relying on fill color.
|
||
Protocol Talents own their mechanic programs and reuse the global Attribute
|
||
registry. Shared secondary values do not scale with the individual protocol’s
|
||
level. Store only the unique primary and Talent base values, and derive their
|
||
progression consistently in calculation and display code.
|
||
|
||
### ISAC editor lifecycle
|
||
|
||
Successful saves have a consistent outcome throughout data management: editing
|
||
an existing record closes the editor and returns the user to the registry;
|
||
creating a new record keeps the editor open with a fresh blank definition for
|
||
rapid consecutive entry. Failed validation leaves the current editor and entered
|
||
values intact. Use a unique action result token so reactive handling runs
|
||
exactly once and does not create update loops.
|
||
|
||
Tiered-definition registries should show their rendered tier effects when the
|
||
text is operationally useful. Use compact wrapping description cells rather than
|
||
replacing meaningful data with a generic “configured” label; retain an explicit
|
||
textual missing state when a tier has no rendered description.
|
||
|
||
Talent mechanics are structured metadata, not free-form prose. Author cooldowns
|
||
on event branches, durations and maximum stacks on state pools, and tier values
|
||
on outcomes through `MechanicProgramEditor`. Description templates use numbered
|
||
expressions (`{1}`, `{2}`) for ordered outcomes and named expressions
|
||
(`{duration}`, `{max_stacks}`) for defined pool mechanics. Named expressions are
|
||
valid only when their corresponding value exists. Cooldown is never embedded in
|
||
the description: render it consistently as `Talent Cooldown: [value] seconds`
|
||
beneath the talent identity or description. Do not imply an absent mechanic with
|
||
a zero value; omit the cooldown line when no branch defines one.
|
||
|
||
### Registry pagination
|
||
|
||
Every primary ISAC registry uses server-side pagination. The shared control
|
||
appears immediately above and visually attached to its table. It shows the
|
||
visible record range and total, previous/next navigation, a compact window of
|
||
page numbers, and row-count presets of 10, 25, 50, and 100. Existing filter
|
||
query parameters must survive page navigation, while changing page size returns
|
||
to page one. Summary metrics remain global or filter-global and must never
|
||
silently describe only the visible page. On narrow screens, retain previous,
|
||
next, current page, and page-size controls before optional page numbers.
|
||
|
||
The row-count presets remain available even when the current result fits on one
|
||
page. Omit only the page navigation when there is no second page. Do not render
|
||
disabled pagination controls merely to preserve the rail's shape.
|
||
|
||
Registries with a meaningful name, title, or agent-identity column place the
|
||
shared server-side search inside this pagination rail. Results update after a
|
||
short typing debounce, so do not place a redundant Search button beside the
|
||
field or label the field as live search. Show `SEARCHING…` only while navigation
|
||
is pending, and provide an explicit clear action whenever a query is active.
|
||
Search resets the page number while preserving the selected KPI filter and
|
||
row-count preset; page navigation preserves the query. Search applies to the
|
||
complete filtered registry before pagination, including visible pending
|
||
proposals, and never only to the current page. Specialized oversight and history
|
||
searches may remain in their richer filter consoles when they search evidence
|
||
beyond a single identity column.
|
||
|
||
At intermediate widths the search spans the pagination rail above its range and
|
||
navigation controls. At mobile widths all groups stack, the input retains a
|
||
usable width, and search, clear, previous, and next remain explicit keyboard and
|
||
touch targets.
|
||
|
||
### Sortable registry columns
|
||
|
||
Every meaningful data column in an ISAC table uses the shared sortable-column
|
||
header. The first activation sorts a new column in its most useful default
|
||
direction; later activations reverse the direction. Place a neutral
|
||
bidirectional indicator immediately before each inactive column label and an
|
||
orange directional indicator immediately before the active column label. Action
|
||
columns do not sort.
|
||
|
||
Sorting applies on the server before pagination. Store the selected column and
|
||
direction in the URL, preserve active search, filters, and row-count settings,
|
||
and return to page one when the sort changes. Server loaders must map public
|
||
sort keys to fixed, allowlisted SQL expressions or in-memory comparators. Never
|
||
interpolate a query-string value into SQL. Composite columns use a documented,
|
||
stable primary value and deterministic tie-breaker. Pending contribution rows
|
||
remain ahead of published records unless the registry explicitly defines a
|
||
different moderation order.
|
||
|
||
Sortable headers must expose column-header semantics and `aria-sort`, remain
|
||
keyboard operable, and show visible hover, focus, active, and selected states.
|
||
At narrow widths, retain the table's existing horizontal overflow behavior so
|
||
labels and sort state do not collapse into ambiguous controls.
|
||
|
||
### Registry metric filters
|
||
|
||
The KPI row above an ISAC registry is an operational filter surface, not passive
|
||
decoration. Use `KpiFilters.svelte` when each metric describes a meaningful
|
||
record subset. The first card returns to the complete current registry or
|
||
search; the remaining cards filter by useful classifications such as active
|
||
state, category, equipment behavior, or restriction state.
|
||
|
||
Filtering is server-backed and occurs before pagination. Filter links preserve
|
||
compatible search and page-size parameters, reset the page number, remain
|
||
bookmarkable, and expose the selected state with both orange emphasis and
|
||
`aria-current`. Cards require pointer, hover, focus-visible, pressed, and
|
||
textually identifiable active states. Every card explicitly says `FILTER →` or
|
||
`SELECTED`; do not rely on KPI-card styling alone to communicate that the
|
||
metrics are controls. Counts describe the full search scope and never only the
|
||
visible page. Replace aggregate facts that cannot filter the affected registry
|
||
with actionable subsets.
|
||
|
||
### Registry row interaction
|
||
|
||
Desktop registry rows are passive data containers unless the entire row opens a
|
||
detail view. Do not apply a whole-row hover surface when only the trailing Edit
|
||
or View action is interactive. Render that action as a compact bordered control
|
||
with hover, focus-visible, and pressed states so its interaction boundary is
|
||
unmistakable.
|
||
|
||
On mobile, a row may become a full-width detail target when the route provides
|
||
an intentional mobile detail interaction. In that case retain the explicit
|
||
`TAP TO VIEW` or `TAP TO REVIEW` text, full-row focus treatment, and minimum
|
||
touch target; do not infer full-row behavior from desktop hover styling.
|
||
|
||
### Image uploads
|
||
|
||
All image uploads use the shared SHD drop-zone treatment and expose three
|
||
equivalent selection paths: a file picker, drag and drop, and clipboard paste.
|
||
The control shows the selected filename and a local preview, but server-side
|
||
format, size, transparency, and normalization checks remain authoritative.
|
||
|
||
### Moderated data states
|
||
|
||
ISAC must distinguish direct editing, contributor proposals, and read-only
|
||
access. Use a compact access banner above the module rather than changing the
|
||
registry layout. Pending proposal counts appear as orange numeric indicators in
|
||
data-navigation items. Proposal lifecycle states use text as well as color:
|
||
pending is orange/actionable, approved is green/configured, and rejected or
|
||
failed is red/archived. Review decisions always use the standard ISAC
|
||
confirmation surface and must never apply a proposal from a table-row click
|
||
alone.
|
||
|
||
Eligible contributors enter ISAC data modules in read-only mode by default. The
|
||
access banner pairs the explicit `READ-ONLY DATA ACCESS` state with a compact
|
||
action that opens the versioned contributor guidelines. Contributor mode may
|
||
only be enabled after affirmative checkbox acceptance. Once enabled, the banner
|
||
changes to orange, explains that saves enter moderation, and offers a
|
||
`RETURN TO READ-ONLY` toggle. Disabling is immediate and reversible and does not
|
||
withdraw existing proposals. Use text for every mode state; color alone is
|
||
insufficient. At narrow widths, stack the explanation and full-width toggle.
|
||
Show contributor access banners only on Data Management modules. Show the
|
||
`DATA MODE` status on those modules and the contributor-guidelines page. Omit
|
||
data-mode controls and language from User Operations, System Oversight, and
|
||
System Configuration because their permissions govern access independently.
|
||
Read-only mode is an inspection surface: hide add controls, row edit actions,
|
||
mutation forms, and editors opened through URL state. Dimming or disabling those
|
||
controls is insufficient. Registry navigation, KPI filters, pagination, search,
|
||
evidence, and other non-mutating inspection controls remain visible and
|
||
interactive.
|
||
|
||
The ISAC command-status cluster includes system state, access state, the themed
|
||
ISAC node identifier, the CI build number, and an explicit `DATA MODE` cell. The
|
||
data-mode cell reports the highest effective authority in this order: `ADMIN`,
|
||
`OVERSIGHT`, `DATA MANAGER`, `CONTRIBUTOR`, then `READ-ONLY`. Use a neutral
|
||
treatment for read-only, orange for contributor, blue for Oversight authority,
|
||
and green for direct-management authority. Every cell requires a label and value
|
||
because color provides supplemental information. At medium widths, arrange the
|
||
cells in a two-column grid and let the data-mode cell span both columns. On
|
||
narrow screens, the cluster spans the command header width.
|
||
|
||
### Oversight proposal corrections
|
||
|
||
User-facing references to moderators and data approvers use the SHD term
|
||
`Oversight`. Distinguish `Community Oversight` from `Data Oversight` when a role
|
||
name must identify its operational domain.
|
||
|
||
Pending proposal review uses three equal decision controls: approve, correct,
|
||
and reject. `CORRECT` is limited to small text or numeric fixes. Present the
|
||
stored form fields in a compact two-column correction grid and identify their
|
||
original field names; long descriptions and structured JSON values use
|
||
textareas. Uploaded file evidence is visible but immutable. Every correction
|
||
must be separately saved and audit logged before approval, and material changes
|
||
should be rejected for contributor revision. Collapse the decision controls and
|
||
correction fields to one column on narrow screens.
|
||
|
||
Proposal evidence is reviewer-facing product data, not JSON-first diagnostics.
|
||
Open review in a wide, scroll-contained confirmation surface and present live
|
||
and proposed values side by side using the visual structure and terminology of
|
||
the source module's editor. Label the two states explicitly as
|
||
`CURRENT LIVE / BEFORE` and `PROPOSED / AFTER`; for additions, replace the empty
|
||
live panel with an explicit `NEW RECORD` state. Stack comparisons on narrow
|
||
screens. Raw stored payloads remain available in a collapsed technical-evidence
|
||
disclosure for troubleshooting and audit support, but must not be the primary
|
||
review surface. Each module should add a purpose-built preview as its editor
|
||
matures; until then, use compact labeled field cards rather than an exposed JSON
|
||
document.
|
||
|
||
Data-navigation links with pending proposals use a dedicated four-column layout:
|
||
module code, flexible label, square orange count cell, then navigation arrow.
|
||
Never insert a count into the ordinary three-column link without changing its
|
||
grid, because the arrow will wrap to another row. The count includes textual
|
||
assistive labeling and strengthens its border and contrast on link hover or
|
||
active state.
|
||
|
||
The same compact count cell identifies actionable work in System Oversight
|
||
navigation. Show it only for queues with unresolved items, such as pending data
|
||
proposals or avatar reviews, and calculate it within the viewer's permissions.
|
||
Do not add zero badges or counts to informational registries such as Audit
|
||
History and System Metrics. Badge text must expose an `awaiting review` label to
|
||
assistive technology; color supplements that meaning rather than replacing it.
|
||
|
||
Registry name search is server-backed and updates as the user types after a
|
||
short debounce; it must search the complete filtered registry rather than only
|
||
the visible page. Preserve active filters and row-count settings, reset results
|
||
to page one, keep input focus, avoid scrolling, and replace browser history so
|
||
each keystroke does not create a navigation entry. Retain an explicit Search
|
||
button for immediate submission and keyboard/accessibility fallback. During
|
||
navigation, expose a textual pending state and suppress duplicate submissions.
|
||
|
||
Builder option grids support an icon-only square mode for small, icon-led
|
||
catalogs such as a gear item's two-to-four compatible Brand Sets. In this mode,
|
||
the compact 58-pixel cells reset the ordinary text-and-icon grid to a single
|
||
centered track, and the transparent icon fills that square. Align the fieldset
|
||
with adjacent compact controls rather than inheriting the standard radio-grid
|
||
top margin. Visible truncated names are omitted. Preserve the complete name as
|
||
the radio control's accessible label and as hover text. Selection, hover,
|
||
pressed, and keyboard-focus states remain on the square perimeter; missing icons
|
||
fall back to the entity initials.
|
||
|
||
Builder level controls enforce item availability without changing the scaling
|
||
curve's origin. T0 and T1 gear and weapons allow levels 1–50; T2 gear and
|
||
weapons allow levels 40–50 because lower-level T2 items are not found in game.
|
||
Their base-value progression still follows the same level-1-based curve.
|
||
Selecting T2 on a weapon below level 40 raises the configured level to 40 and
|
||
calculates the ordinary level-40 curve value; never rebase level 40 as T2 level
|
||
|
||
1. Slider bounds, direct-input validation, displayed bounds, and clamping must
|
||
all enforce the same availability minimum.
|
||
|
||
ISAC ranges that represent observed values retain their explicit reference
|
||
level. The progression curve still has a level-1 origin, but builder scaling
|
||
must calculate the ratio between the target level and the stored observation's
|
||
`reference_level`. Do not treat every observed endpoint as a level-1 value
|
||
merely because the curve begins there.
|
||
|
||
Weapon damage is the exception to reference-observation scaling: each
|
||
weapon-tier damage range is stored as a hidden base and must be multiplied
|
||
directly by `weaponMultiplier(selectedLevel)`. Changing weapon level remaps the
|
||
selected damage value into the newly calculated range. Shared core attributes
|
||
remain level-50 reference profiles and use ratio scaling independently.
|
||
|
||
Gear base Health and Armor follow the same hidden-base principle. Multiply their
|
||
stored per-item endpoints directly by `gearMultiplier(selectedLevel)`, truncate
|
||
only for display, and remap the user's selected value proportionally when gear
|
||
level changes. Do not apply this rule to rolled Attributes or the shared
|
||
core-allocation profile, which retain independent reference semantics.
|
||
|
||
### Shared core allocation
|
||
|
||
Firepower, Toughness, and Engineering use one system-wide tier profile shared by
|
||
gear and weapons. Maintain the T0/T1/T2 nominal ranges in ISAC Global
|
||
Configuration rather than repeating them on every item editor. The initial
|
||
level-50 profiles are T0 `30–78`, T1 `36–94`, and T2 `44–112`. Global
|
||
configuration mutations follow ordinary contributor moderation and append-only
|
||
ISAC audit rules.
|
||
|
||
The three nominal ranges define a combined allocation pool, not three hard
|
||
per-stat clamps. At a given level, the valid total lies between three times the
|
||
scaled nominal minimum and three times the scaled nominal maximum. An individual
|
||
core may be zero or exceed the nominal maximum when points are redistributed, up
|
||
to the entire pool maximum. Builder gear and weapon editors show three
|
||
sliders/direct inputs plus an explicit current-total versus valid-pool readout;
|
||
out-of-pool totals use textual red/restricted feedback. Both equipment families
|
||
contribute their configured cores to the build summary. Treat this
|
||
redistribution model as empirical and keep it configurable as more in-game edge
|
||
cases are observed.
|
||
|
||
Pending records may be used as dependencies in later proposals by any
|
||
contributor. Render these choices in the ordinary assignment control with a
|
||
restrained orange border/background and the explicit text `PENDING` plus the
|
||
proposer’s display name; never present them as live data. Approval is dependency
|
||
ordered: a dependent proposal stays pending until every referenced proposal is
|
||
approved, while rejected or failed dependencies block it. This state must be
|
||
conveyed by text as well as color and must remain legible in compact and
|
||
responsive editor layouts.
|
||
|
||
Large many-to-many selections use the shared searchable assignment control,
|
||
including weapon talent pools, gear talent compatibility, and compatible brand
|
||
sets. The control keeps assigned records visible as removable chips, filters
|
||
available records by their displayed identity, limits the rendered result set,
|
||
and submits canonical hidden inputs. Configure its subject labels, qualifiers,
|
||
and empty-state copy for the entity being assigned rather than embedding
|
||
talent-specific language in the shared component. Pending contributor records
|
||
retain their orange treatment and named proposer in both search results and
|
||
dependency workflows.
|
||
|
||
Audit History may use a five-column KPI filter rail when all durable operational
|
||
domains need first-class visibility. It retains the standard compact KPI height
|
||
and collapses through the shared dashboard breakpoints; do not increase card
|
||
height or create a second row solely to accommodate the fifth domain.
|
||
|
||
Inherent permissions that cannot be removed through role or user assignment use
|
||
the compact blue information rail above the affected access controls. Always
|
||
name the baseline and enumerate its capabilities so operators do not mistake an
|
||
empty role assignment for an account with no effective access.
|
||
|
||
### Mobile registry detail targets
|
||
|
||
On narrow screens, a non-editing registry row with one canonical detail or
|
||
review destination becomes a full-row tap target. Use a real stretched link when
|
||
the destination is another route and a transparent button when it opens an
|
||
in-page detail surface. Keep the explicit desktop `VIEW`, `REVIEW`, or
|
||
`EVIDENCE` action, and add a visible mobile cue at the bottom of the row so the
|
||
interaction is discoverable.
|
||
|
||
The target must expose an accurate accessible name, show the standard orange
|
||
focus-visible outline, provide pressed feedback, and meet a minimum 48-pixel tap
|
||
height. Do not apply this pattern to edit, delete, approve, or other mutating
|
||
actions, and do not stretch a target across rows containing independent
|
||
interactive controls.
|
||
|
||
### Avatar Oversight
|
||
|
||
Custom avatars are active immediately and enter a separate Avatar Oversight
|
||
queue. The registry uses compact image-evidence cards rather than a text table:
|
||
portrait, explicit lifecycle state, agent identity, submission time, normalized
|
||
size, reviewer, and note stay visible together. Pending is orange, approved is
|
||
green, and removed is red; withdrawn and superseded remain neutral. State text
|
||
is mandatory.
|
||
|
||
Review uses the standard ISAC modal and two equal decision controls. Approval
|
||
records the review without changing the active image. Removal requires a reason
|
||
and explicit confirmation, deletes the custom file, and returns the account to
|
||
the default SHD portrait. A stale review must never act on a newer upload.
|
||
Historical entries retain metadata and audit evidence even when their image is
|
||
no longer available. At narrow widths cards become one column, retain a large
|
||
portrait preview, and expose a minimum 44-pixel review action.
|
||
|
||
### Notification network
|
||
|
||
Authenticated navigation exposes a compact inbox glyph with a numeric unread
|
||
badge; mobile navigation provides the same explicit `INBOX` destination and
|
||
count. Notifications live under the agent-profile namespace and use an explicit
|
||
profile context trail back to account controls. The inbox is a dense
|
||
communication registry with a source rail, category, title, timestamp, body,
|
||
destination, and textual read state. Unread messages use the orange action rail.
|
||
Mandatory ISAC notices use the blue operational rail and must always remain
|
||
visible in the in-app inbox.
|
||
|
||
Preferences are channel-by-category rather than global. Each category controls
|
||
in-app, browser, and email delivery independently. ISAC in-app delivery is
|
||
locked on, while its browser and email channels remain optional. Email defaults
|
||
to off and offers `OFF`, `IMMEDIATE`, and `DAILY DIGEST`; browser delivery must
|
||
follow an explicit browser permission gesture. Never imply background push when
|
||
only active-site browser polling is available. At narrow widths preference rows
|
||
stack their identity above channel controls and notification entries collapse
|
||
their source rail above the message.
|
||
|
||
The main Agent Profile surfaces the five most recent enabled inbox messages
|
||
before authored-content modules and includes unread count as a profile metric.
|
||
This preview preserves mandatory, unread, source, and category states, uses
|
||
single-line truncation at desktop density, and links to either the notification
|
||
destination or full profile inbox. On mobile, metadata becomes its own row and
|
||
message body copy may wrap.
|
||
|
||
Inbox messages use sender identity and semantic tone. ISAC sources use the SHD
|
||
system mark, blue system labeling, and an explicit `SYSTEM` descriptor;
|
||
community activity uses an agent portrait and `AGENT` descriptor. Positive
|
||
outcomes use green, adverse or corrective outcomes use red, and informational
|
||
content stays neutral. Message titles and body copy state the actual outcome; do
|
||
not expose internal sentiment labels such as `POSITIVE`, `NEGATIVE`, or
|
||
`NEUTRAL`. Reserve visible badges for operationally meaningful severity such as
|
||
`WARNING` or `ERROR`, while the message wording remains understandable without
|
||
depending on color alone.
|
||
|
||
The inbox command header pairs the page identity with a compact bordered unread
|
||
summary and a same-height preferences action. Filter selects and adjacent
|
||
actions share a 40-pixel control height and vertically centered labels. Within
|
||
each message, the tone/title/timestamp header uses modest vertical padding and a
|
||
subtle lower rule: keep it dense, but never collapse it into a text-height
|
||
strip. On mobile the unread summary and preferences action share one grid row,
|
||
while filter controls stack into full-width, minimum 44-pixel targets.
|
||
|
||
Page hierarchy uses the shared eyebrow breadcrumb rather than a separate
|
||
breadcrumb row above a command header. It retains the short orange rule, renders
|
||
ancestors as orange links, separates levels with a muted slash, and marks the
|
||
final item as the current page. A top-level page may use a single current item.
|
||
Do not duplicate the same hierarchy in both an eyebrow and a second contextual
|
||
navigation strip; this creates visual overlap and wastes vertical space. The
|
||
breadcrumb always uses intrinsic height and must not inherit the full-height
|
||
primary-navigation treatment. Likewise, in-page command and message headings
|
||
must use their named component classes rather than the global application
|
||
`header` element treatment.
|
||
|
||
`VIEW DETAILS` opens the standard in-page modal rather than navigating
|
||
immediately. The modal repeats sender, source, category, semantic tone, time,
|
||
full message body, read control, and related-page destinations. Keep the sender
|
||
header and utility footer fixed while the message and action area scrolls. Group
|
||
destination actions beneath an `AVAILABLE ACTIONS` label in a regular grid;
|
||
reserve the footer for message state and closing the modal. Opening the modal
|
||
moves focus to its close control. Trap keyboard focus inside it, support Escape
|
||
and backdrop dismissal, and return focus to the originating `VIEW DETAILS`
|
||
control after closing. Inbox cards show up to four lines of body copy at reading
|
||
size before truncation. Place the per-message read control beside the timestamp
|
||
so message state remains separate from workflow actions.
|
||
|
||
ISAC message content uses the structured system-transmission body. A compact
|
||
blue `ISAC TRANSMISSION` kicker precedes the summary, and recognized supporting
|
||
fields such as `OVERSIGHT REASON`, `REQUIRED ACTION`, or `DETAILS` become a
|
||
labeled detail row beneath a subtle divider. The expanded message view uses the
|
||
same hierarchy at reading size. Community messages remain conversational body
|
||
copy; do not apply the system-transmission frame to agent comments.
|
||
|
||
Inbox entries expose two distinct actions. `VIEW DETAILS` opens the complete
|
||
message when its four-line preview truncates longer copy. A separate bordered
|
||
orange response action opens the known workflow and uses specific language such
|
||
as `UPLOAD NEW AVATAR`, `REVISE CONTRIBUTION`, or `VIEW BUILD & REPLY`; never
|
||
substitute a generic destination label when the notification type is known. Lay
|
||
out these controls in an auto-fitting grid so each label remains intact. The
|
||
detail modal uses the same response labels in a three-column grid where space
|
||
permits. On mobile, response actions become full-width 44-pixel targets.
|
||
|
||
Inbox query controls use two compact radio-backed segmented selectors. `SHOW`
|
||
switches between all, unread, and read messages. `SORT` offers newest, oldest,
|
||
and unread-first order. Give both selectors the same compact width. Each
|
||
selection applies without a submit button. Live search matches message titles,
|
||
bodies, and sources across the paginated result set. At narrow widths, the
|
||
selectors stack and retain 44-pixel targets.
|
||
|
||
Use the shared `SegmentedChoice` component for every static, scannable ISAC
|
||
choice set containing two through six options. Radio mode represents one
|
||
required choice; checkbox mode represents additive independent choices. This
|
||
rule applies equally to editors and registry filters: do not introduce a native
|
||
dropdown merely to save vertical space. Use the shared `SearchableAssignment`
|
||
component in single or multiple mode when there are seven or more options, when
|
||
the options come from a growing data registry, or when search materially helps
|
||
recognition. Compact mode is the standard treatment for filter bars and dense
|
||
repeated rows; full mode is used for primary relationships.
|
||
|
||
Native selects are not a default ISAC control. Retain one only when a documented
|
||
browser-native behavior cannot be represented accessibly by either shared
|
||
component. Such an exception must be called out in this design system in the
|
||
same change. Both shared choice patterns expose explicit selection, hover,
|
||
pressed, focus-visible, disabled, empty/all, responsive, and 44-pixel
|
||
mobile-target states so modules do not reimplement them.
|
||
|
||
Numeric inputs inside ISAC use overwrite-first focus behavior: focusing an
|
||
enabled `type="number"` control selects its complete current value so a
|
||
contributor can immediately type a replacement instead of appending to a default
|
||
zero. This behavior belongs to the shared ISAC layout boundary and must not be
|
||
reimplemented in individual modules. Disabled numeric controls remain
|
||
unfocusable and unchanged.
|
||
|
||
`SegmentedChoice` supports two restrained density variants. Icon-only segments
|
||
may omit visible text when a canonical, unambiguous game icon exists; they must
|
||
retain an accessible label and hover title. Do not render generic dots, squares,
|
||
checkbox facsimiles, or radio facsimiles inside segments. The selected
|
||
background, orange text, and lower rail communicate state. Keep visible text or
|
||
an icon in every option.
|
||
|
||
### Skill Chip data console
|
||
|
||
Place two shared configuration cards above the Skill Chip definition registry.
|
||
The `SHARED PRIMARY PROFILE` card contains the fixed Skill Duration, Skill
|
||
Radius, Skill Cooldown Recovery, and Skill Intensity rows, with direct minimum
|
||
and maximum fields for Standard, Specialized, Superior, and High-end. Its
|
||
summary shows the configured count for each quality and the `NOT YET DEFINED`
|
||
calculation state. The `SHARED SECONDARY POOL` card contains repeatable
|
||
searchable Attribute rows with direct minimum and maximum fields for
|
||
Specialized, Superior, and High-end. Its summary shows each quality's fixed
|
||
capacity and the shared option count. Each card opens its own editor and closes
|
||
that editor after a successful save. Validation keeps the affected editor open
|
||
with its values intact. Successful saves append
|
||
`game_data/skill_chip_primary_profile.updated` or
|
||
`game_data/skill_chip_secondary_pool.updated`.
|
||
|
||
State the fixed secondary capacities in the pool card and editor: Standard zero,
|
||
Specialized one, Superior two, and High-end two. Skill Chip fields never show an
|
||
item-level control or level-based preview. Quality labels use the global green,
|
||
blue, purple, and yellow treatments; orange remains reserved for actions and
|
||
selection. On narrow screens, profile summaries stack, endpoint matrices scroll
|
||
inside their cards, and actions retain 44-pixel targets.
|
||
|
||
Definition editors follow the dense staged pattern: ability assignment, identity
|
||
and icon, one per-set 2-piece bonus, then the optional 3-piece Talent. Place the
|
||
Talent assignment control before one disclosure that contains the entire Talent
|
||
workspace: identity, description, quality-mix preview, and
|
||
`MechanicProgramEditor`. The disclosure summary shows the configured Talent name
|
||
or `TALENT WORKSPACE`, the quality-scaled outcome count, and an explicit
|
||
`EXPAND` or `COLLAPSE` action. Existing Talents start collapsed when an operator
|
||
opens a definition. Assigning a Talent or receiving a Talent validation error
|
||
opens the workspace. Native disclosure semantics expose the expanded state, keep
|
||
draft state mounted while collapsed, and provide a 44-pixel mobile target.
|
||
|
||
Every equipped chip quality counts toward the two-piece threshold. The set-bonus
|
||
preview uses four steps for zero through three equipped High-end chips and the
|
||
formula `minimum + (maximum − minimum) × h / 3`; only High-end chips increase
|
||
`h`. Do not duplicate calculated values as editable fields.
|
||
|
||
### ISAC record identity controls
|
||
|
||
Game-data icon editors use the shared `--isac-icon-editor-width` footprint (150
|
||
pixels on desktop) regardless of module. Identity layouts allocate that fixed
|
||
column to `IconUploadField`, give the record name the flexible dominant column,
|
||
and stack both controls at mobile widths. Do not enlarge an upload drop-zone to
|
||
fill spare identity-row space.
|
||
|
||
Icon-enabled consecutive-entry editors pass a successful-add result token into
|
||
the shared upload control. Advancing that token clears the native file input,
|
||
temporary preview URL, filename, drag/paste feedback, and validation state.
|
||
Reset only after a validated add succeeds. Failed saves preserve the selected
|
||
image; successful edits close the editor.
|
||
|
||
The primary `name` field in each ISAC data editor is a 46-pixel header-level
|
||
input with larger, heavier text. It gives long registries a consistent first
|
||
reading point while keeping secondary metadata compact.
|
||
|
||
`SearchableAssignment` is the standard relationship picker for long Attribute,
|
||
Talent, event, and compatibility lists. Multiple mode manages additive sets;
|
||
single mode presents the same searchable selected/result treatment for one
|
||
relationship. Prefer these modes over native selects once a source registry is
|
||
large enough that scanning a dropdown is inefficient. The selected record,
|
||
pending-contribution state, keyboard focus, and remove interaction must remain
|
||
explicit in both modes.
|
||
|
||
Records with established visual identity may supply an optional square icon.
|
||
Standard assignment lists show it at 32 pixels in result rows and 24 pixels in
|
||
selected chips. An icon-first multiselect may use the `visual-grid` presentation
|
||
for a finite visual registry. Its compact tiles use a 38-pixel icon without
|
||
persistent tile text. Hover and keyboard focus reveal the record name, while the
|
||
accessible label includes the name and assignment state. The orange inset edge
|
||
marks selected tiles. Weapon Talent 1 and Talent 2 pools and the Backpack and
|
||
Body Armor talent pools use this grid. Use the shared missing-item artwork when
|
||
a record lacks an icon. Render the full eligible set without a search,
|
||
result-count row, item cap, or internal scroll region; the section header owns
|
||
the selected count. Reflow tiles without changing keyboard order.
|
||
|
||
Use the `toggle-grid` presentation for a small fixed registry whose text labels
|
||
are the primary recognition aid. Each 44-pixel-or-taller option uses checkbox
|
||
semantics and shows only the record name. The orange action edge marks the
|
||
selected state, and the accessible label includes that state. Weapon mod slot
|
||
selectors use this presentation so an operator can toggle each slot by clicking
|
||
its name. Keep all options visible and preserve DOM order as the grid reflows.
|
||
|
||
Every ISAC relationship to an Attribute uses `SearchableAssignment`; native
|
||
attribute dropdowns are not permitted because the registry is expected to
|
||
contain hundreds of records. Use full mode for primary editor sections and
|
||
multi-value pools. Use compact single mode inside repeated effect, bonus, or
|
||
augmentation rows: its selected record and search field remain inline while the
|
||
filtered result registry opens as an anchored overlay. The compact overlay must
|
||
layer above adjacent rows, retain pending-record labels, and collapse to one
|
||
column on narrow screens.
|
||
|
||
Gear identity editing uses the shared segmented radio treatment for both Gear
|
||
slot and item tier. Show all six slots together and all three tiers together so
|
||
contributors can verify classification without opening a menu. The record name
|
||
remains the dominant text field; at medium widths it occupies a full row above
|
||
the two selectors. On narrow screens the slot selector becomes a three-by-two
|
||
grid, both selectors use at least 44-pixel targets, and changing slot clears
|
||
incompatible Talent relationships exactly as the former selector did. Gear slot
|
||
segments use icon-only controls with accessible slot names; registry labels
|
||
retain icon and text for rapid table scanning. Tier segments use the compact
|
||
game notation `T0`, `T1`, and `T2`, and rely on the selected rail and color; do
|
||
not expand these to “Tier 0” inside dense segmented controls. On desktop,
|
||
icon-only Gear slot segments are square 32-pixel cells so their classification
|
||
rail stays compact and the adjacent record-name input receives the dominant
|
||
width. Increase those cells to square 44-pixel targets at mobile sizes without
|
||
reintroducing visible slot text.
|
||
|
||
Weapon-category editing follows the same compact icon-rail treatment: Shotgun,
|
||
Rifle, MMR, AR, LMG, and SMG use their canonical weapon silhouettes in square
|
||
32-pixel desktop cells and 44-pixel mobile cells, with accessible names and
|
||
hover titles retained. Exotic remains an independent icon-backed status because
|
||
an Exotic weapon must also retain its underlying weapon category. Weapon Damage
|
||
Type follows the same icon-only treatment when canonical Blast, Pierce, and
|
||
Shredding marks are available. Exotic status is a single square checkbox whose
|
||
icon, orange rail, and background show its checked state; no visible “Exotic
|
||
weapon” label is repeated inside the control. Weapon registry rows show both the
|
||
category silhouette and, when applicable, the Exotic mark alongside the textual
|
||
class for rapid scanning.
|
||
|
||
Weapon Tier Progression begins at the selected Native Tier. Lower tier cards
|
||
remain visible for orientation but are disabled, desaturated, and explicitly
|
||
labeled unavailable; their values are neither required nor persisted. Each
|
||
available tier has one Damage range labeled with the selected damage-type icon
|
||
and one shared Core range for Firepower, Toughness, and Engineering, represented
|
||
by all three primary-attribute icons. Registry completeness compares configured
|
||
tiers with the number possible from the weapon’s Native Tier. Archive Weapon
|
||
uses the standard separated ISAC destructive-action control on the left side of
|
||
the editor action band.
|
||
|
||
Root-level static PNGs are interface icons and use content-fitted transparent
|
||
bounds. Run `npm run assets:trim-icons` after adding or replacing them. The
|
||
normalizer trims fully transparent padding, restores a two-pixel transparent
|
||
safety margin so antialiased edges never touch the canvas, preserves RGBA PNG
|
||
output, and leaves portrait/avatar and SVG asset classes untouched.
|
||
|
||
### Shared equipment profiles
|
||
|
||
Configuration inherited by every item of a finite equipment type belongs in a
|
||
collapsible shared-profile registry above the item table. Each profile card
|
||
states its type, required slot count, configured state, and a compact summary;
|
||
selecting it opens a separate dense editor and closes the individual-record
|
||
editor. Successful saves close the profile editor and return to the registry.
|
||
|
||
Gear Tactical Augment profiles use this pattern for all six gear types.
|
||
Backpacks and Body Armor expose four required slots; Holsters, Gloves, Knee
|
||
Pads, and Masks expose three. Augment 01 contains one searchable Attribute, one
|
||
numeric effect value, and an unlock cost. Later slots expose only their unlock
|
||
cost because their effects are fixed base-item upgrades: three-slot profiles use
|
||
+50% and +100%, while four-slot profiles use +40%, +70%, and +100%. Holsters,
|
||
Masks, and Backpacks modify the equipped item's base Health; Gloves, Knee Pads,
|
||
and Body Armor modify that item's base Health and Armor. These percentages never
|
||
apply to the overall character total. Every augment slot stores separate
|
||
non-negative whole-number unlock costs for item Tiers 0, 1, and 2. Show all
|
||
three costs together in registry summaries and in a compact three-column cost
|
||
fieldset within the editor; the builder shows only the cost matching the
|
||
equipped item's tier. Fixed upgrades use a green inherited-value panel to
|
||
distinguish governed data from editable orange actions. At narrow widths profile
|
||
cards and augment editor cards reduce to a single column while retaining
|
||
44-pixel interactive targets.
|
||
|
||
### Loadout workbench
|
||
|
||
The builder is a three-rail tactical workbench: compact equipment positions on
|
||
the left, the currently selected item editor in the center, and a sticky live
|
||
totals summary on the right. At medium widths the summary becomes a full-width
|
||
lower rail; on mobile all three rails stack, with equipment first, editing
|
||
second, and results third. Equipment positions remain explicit even when empty
|
||
so players can see loadout completeness.
|
||
|
||
Use the shared `BuilderPicker` for builder catalogs and Attribute pools. It
|
||
combines an always-visible current selection with a searchable overlay, icon or
|
||
tactical fallback mark, classification metadata, selected state, and conflict
|
||
state. Conflicting catalog entries remain visible but disabled so restrictions
|
||
such as the single-exotic-weapon rule are explained rather than hidden.
|
||
|
||
Numeric instance values display their authoritative minimum and maximum beside
|
||
the field and clamp to that range on completion. Always-on item rolls, fixed
|
||
bonuses, inherited profiles, enabled augments, and activated set bonuses feed
|
||
the live totals immediately. Current Builder and shared Build pages stop at
|
||
these deterministic equipped-item totals. Conditional Talent outcomes, weapon
|
||
and Skill DPS, encounter assumptions, activation profiles, rotations, and
|
||
simulation remain planned. Render those capabilities as separate `COMING SOON`
|
||
panels, with visible text rather than color alone.
|
||
|
||
Loadout summaries name selected Talents, Attributes and their exact values,
|
||
nodes, and Skill Chips. Do not replace these selections with configured item
|
||
counts. Build identity includes a required name plus optional strengths summary
|
||
and usage guide. Shared build views include those author-written fields so
|
||
another player can understand the build's role and operating sequence.
|
||
|
||
### Pending ISAC registry records
|
||
|
||
Pending additions appear directly in the same paginated ISAC registry as live
|
||
records and in every compatible relationship picker. They use a restrained
|
||
orange-tinted row, an explicit `PENDING` state, and proposer attribution.
|
||
Pending rows are read-only in module registries; changes remain the authority of
|
||
the Data Oversight review interface. Successful contributor submissions refresh
|
||
the registry immediately and follow the same editor lifecycle as a direct save.
|
||
Never rely on the tint alone to communicate moderation state.
|
||
|
||
Gear and weapon level are builder-instance state, never part of an ISAC item
|
||
definition. Each equipped item stores its own level from 1–50 in the local or
|
||
persisted build. Range endpoints are calculated from the documented level curve
|
||
and stored reference level; provisional portions of that curve must be
|
||
identified in text as estimated.
|
||
|
||
### Registry relationship icon rails
|
||
|
||
When a table relationship contains a small bounded set of visually identified
|
||
records, show a compact icon rail instead of a numeric relationship count. Rails
|
||
use 30-pixel square cells with four-pixel spacing, uploaded transparent icons,
|
||
full accessible names, and native hover titles. Missing artwork falls back to a
|
||
short orange text mark rather than removing the relationship.
|
||
|
||
Use this pattern only for small bounded sets that remain scannable, such as the
|
||
two-to-four compatible Brand Sets on Gear. Long or unbounded relationships
|
||
continue to use counts, searchable inspection, or expanded detail views. Public
|
||
Gear cards use the same rail for compatible Brand Sets and available Talents so
|
||
players can identify actual options instead of reading a count. Each icon
|
||
retains its accessible name and hover title, and missing artwork uses the shared
|
||
placeholder without suppressing the relationship. Relationship icons are
|
||
buttons: activating one opens a modal quick view with the shared database card
|
||
component and the same facts, tier hierarchy, mechanic rows, and actions shown
|
||
in that record's public registry. The shared card renders a pinned Community
|
||
Note when the related record has one; quick views do not load the discussion
|
||
thread. The overlay traps keyboard focus, returns focus to its trigger when
|
||
closed, and closes through its explicit close action, backdrop, or Escape key.
|
||
Do not render an empty Talent rail on item types that cannot equip Talents.
|
||
|
||
### Public game-database registries
|
||
|
||
The public Database is a player-facing reference surface, separate from the ISAC
|
||
editing workflow. Its index exposes eight durable categories: Gear, Weapons,
|
||
Weapon Mods, Gear Mods, OS Protocols, Talents, Brands, and Skill Chips.
|
||
Attributes are implementation vocabulary resolved into the facts and effects
|
||
shown on those records; do not promote Attributes to a public top-level
|
||
category.
|
||
|
||
Each index category is a fully interactive square registry card with its full
|
||
player-facing category name as the first and strongest element. Record count and
|
||
availability are supporting metadata in the footer; operational states such as
|
||
“active registry” or “intake” must never compete with the category identity. Use
|
||
the larger display-weight category name with a short orange identity rail;
|
||
render any adjacent count in muted telemetry styling. Cards retain a concise
|
||
scope statement, visible hover/focus state, and pressed feedback. A category
|
||
page uses the shared compact category rail, live name search, pagination, and a
|
||
responsive card grid. Record cards use the same hierarchy:
|
||
|
||
- a fixed icon cell and compact identity header;
|
||
- small textual badges for quality, tier, or exceptional state;
|
||
- bordered fact cells for primary values;
|
||
- relationship lines and tier descriptions only when applicable.
|
||
|
||
When a record represents an ordered progression rather than independent facts,
|
||
use the stacked fact treatment. Brand Set bonuses are shown vertically in two-,
|
||
three-, then four-piece order; do not add a redundant “3/3 bonuses” badge when
|
||
all three rows are already visible.
|
||
|
||
Weapon cards also use stacked facts. Their level-50 Damage range is the primary
|
||
fact: a taller orange-railed row with enlarged values and the Damage Type in the
|
||
label. Public damage is calculated from the stored level-1 endpoints using the
|
||
same `weaponBaseRange` curve as the builder; never label the configured base
|
||
endpoints as level-50 values. Weapon Talent 1 and Talent 2 pools use separate
|
||
clickable icon rails and the standard Talent quick view.
|
||
|
||
Show each weapon's named Mod slots and slot pictograms between its performance
|
||
facts and Talent pools. Native T0 weapons display the complete T1/T2 slot set.
|
||
Mark the slot that is absent at T0 with the blue information state and an
|
||
explicit `T1+` label so the unlock does not rely on color alone. Other slots use
|
||
the neutral telemetry treatment. If ISAC has no slot data, show
|
||
`MOD SLOT DATA NOT CONFIGURED`. Do not show the weapon-category bonus count as
|
||
`BASE BONUSES`; that identical count does not help players compare weapon
|
||
definitions.
|
||
|
||
Record cards may end with contextual actions that connect related public
|
||
registries. Actions use the compact orange tactical-button treatment and encode
|
||
their destination filter in the URL. Brand cards provide a “find Gear” action
|
||
that opens the Gear registry with that Brand selected; the same action must
|
||
remain available in Brand quick views.
|
||
|
||
Discussion and correction controls form a separate utility group at the footer's
|
||
trailing edge. These icon controls use neutral surfaces and borders at rest so
|
||
players do not mistake them for quality badges or primary actions. The
|
||
discussion control shows the visible-message count when the count is nonzero.
|
||
Both controls require accessible names and visible hover and focus states.
|
||
|
||
Opening a discussion displays a routed modal with the complete item card above
|
||
the thread. The modal keeps the record and conversation in one scroll region,
|
||
traps keyboard focus, closes through Escape or the backdrop, and fills the
|
||
viewport on narrow screens.
|
||
|
||
### Public comment threads
|
||
|
||
Use the Agent profile thread as the standard presentation for public comments.
|
||
Root comments sit directly on the page or modal surface without a card border,
|
||
fill, or shadow. Align comment bodies, actions, reply composers, and removal
|
||
tombstones with the author identity. Nested replies add one thin structural rail
|
||
and a small left inset; do not wrap replies in another panel. Limit visual
|
||
indentation on narrow screens while preserving the logical thread depth.
|
||
|
||
Pinned, removed, pending, and moderation states use explicit text. A pinned
|
||
label may use Signal Orange, but it must not add a border or background around
|
||
the whole comment. Removal tombstones retain reply context without recreating
|
||
the missing comment as a filled card.
|
||
|
||
Database Community Oversight and Agent profile owners may pin one visible root
|
||
comment on their respective threads. Render the pinned conversation first and
|
||
keep its replies attached in reading order. Place pin and unpin controls in the
|
||
comment overflow menu.
|
||
|
||
Pinned Community Note previews on database cards use the muted Armor palette
|
||
instead of action orange. Render their sanitized Markdown with the shared
|
||
`MarkdownContent` component so links, lists, paragraphs, and emphasis match the
|
||
full discussion message.
|
||
|
||
Each visible comment places `REPLY` and a low-chrome `...` overflow trigger in
|
||
the action row. The menu contains follow and report actions for signed-in Agents
|
||
who may use them, author or Community Oversight removal, and Community Oversight
|
||
pinning where the target supports a pinned note. Leaf removals delete the
|
||
message. A removed message with surviving replies becomes an unboxed tombstone
|
||
that identifies whether the poster or Community Oversight removed it. Scrollable
|
||
discussion modals reserve enough space after the final message for the complete
|
||
overflow menu to open above the scroll boundary.
|
||
|
||
Cards display canonical active data only. Attribute references must be resolved
|
||
to readable names, values, and units instead of exposing IDs or raw JSON.
|
||
Missing uploaded art uses the standard missing-item placeholder. Desktop layouts
|
||
use three record columns, intermediate layouts use two, and narrow layouts use
|
||
one. The eight-category rail reduces from eight to four to two columns. Preserve
|
||
keyboard focus, pressed feedback, reduced-motion behavior, and readable textual
|
||
state in every layout.
|
||
|
||
Category-specific discovery uses the shared `DatabaseDiscoveryConsole`. It joins
|
||
the tactical filter matrix, live registry search, result range, pagination, and
|
||
page-size controls inside one connected instrument; do not stack separate
|
||
bordered filter and pagination bars. Categories without facets retain the same
|
||
console with search and pagination alone.
|
||
|
||
The matrix is a disclosure inside that console. It starts expanded on desktop
|
||
and collapsed on viewports at or below 700px when no filters are active. Active
|
||
filters make the initial state expanded. Its header always exposes the active
|
||
filter count and an explicit `SHOW FILTERS` or `HIDE FILTERS` action, while
|
||
search and pagination remain visible when the matrix is closed. Preserve the
|
||
user's manual disclosure choice in session storage rather than carrying it
|
||
between unrelated browser sessions.
|
||
|
||
Filters apply immediately, remain encoded in the URL, reset pagination, and
|
||
compose with name search. Multiple selections inside one facet are inclusive
|
||
(`OR`); active facet groups combine restrictively (`AND`). For example,
|
||
selecting two Brands and four Talents returns Gear matching any selected Brand
|
||
and any selected Talent. Never implement multi-select facets as an implicit
|
||
match-all within the same group.
|
||
|
||
Use segmented icon choices for bounded visual vocabularies of six or fewer, such
|
||
as Gear slots. Use the matching searchable multi-select list for growing sets
|
||
such as Brands and Talents. Always expose selected counts, a single clear
|
||
action, `aria-pressed` state, keyboard focus, and explicit text explaining the
|
||
combination rule. At intermediate width, the bounded facet spans the row above
|
||
two searchable facets; on narrow screens all facet groups stack vertically.
|
||
Weapon discovery applies this pattern to weapon-family icons, damage-type icons,
|
||
and the searchable pool of compatible Talents. Talent facet rows show the
|
||
rendered Tier I description beneath the name. Talent searches match both fields
|
||
case-insensitively so mechanical phrases can discover talents even when the
|
||
talent name is unknown. Brand facets similarly index the names of all set-bonus
|
||
Attributes, allowing players to search by the desired mechanic without exposing
|
||
that metadata as extra visual clutter.
|
||
|
||
Public database command headers are content-sized and must explicitly override
|
||
the global 76-pixel site-header rule. Their eyebrow, title, description, count,
|
||
and index action remain inside the bordered command surface at every scale.
|
||
Children use `min-width: 0`, long titles may wrap, and category navigation
|
||
tracks use zero-minimum grid columns so translated or enlarged text cannot force
|
||
horizontal page overflow.
|
||
|
||
### Build persistence and sharing
|
||
|
||
The builder distinguishes device persistence from account persistence.
|
||
`SAVE LOCALLY` writes a working draft to the current browser. Signed-in agents
|
||
also receive one account-save action paired with an explicit visibility
|
||
selector:
|
||
|
||
- `PRIVATE` is owner-only.
|
||
- `UNLISTED` is accessible by direct link but excluded from discovery.
|
||
- `PUBLIC` is accessible by direct link and included in the public archive.
|
||
|
||
Keep visibility adjacent to the account-save action and explain its selected
|
||
state in plain language. Show Build Uplink after an Agent saves a Build. Public
|
||
and unlisted Builds expose its active controls; private Builds show the locked
|
||
state. Public and unlisted Build pages are read-only tactical summaries; owner
|
||
editing returns to the builder.
|
||
|
||
Build Uplink uses a compact tactical control surface. Use one bordered dark
|
||
panel with a raised telemetry header, a textual `PUBLIC LINK READY` or
|
||
`UNLISTED LINK READY` state, and a small orange signal marker. The primary
|
||
`SHARE BUILD` action opens the native Web Share sheet when the browser supports
|
||
it. Keep `COPY LINK` visible as a separate explicit action for every eligible
|
||
Build. When Web Share is unavailable, promote Copy Link to the primary action
|
||
instead of presenting a control that cannot run. Supporting copy may state that
|
||
Discord renders the Build preview after an Agent posts the link. It must not
|
||
imply that SHD.build posts to Discord or operates a bot.
|
||
|
||
Private and unsaved Builds use the locked Uplink state. Show `PRIVATE BUILD` or
|
||
`UNSAVED BUILD`, `PUBLIC LINK UNAVAILABLE`, and a short instruction to change
|
||
visibility or save. Render no active Share or Copy Link control in that state.
|
||
Do not expose a crawler-preview action or suggest that owner access makes a
|
||
private Build shareable.
|
||
|
||
Uplink actions retain textual pending, success, cancellation, unsupported, and
|
||
failure feedback. They use at least 44-pixel targets, orange focus-visible
|
||
treatment, pressed feedback, and disabled duplicate-action protection. Stack
|
||
Share above Copy Link at phone widths and remove pressed motion under
|
||
`prefers-reduced-motion`. On narrow layouts, persistence controls and
|
||
shared-loadout columns also stack vertically.
|
||
|
||
### Tiered compatibility editors
|
||
|
||
When compatibility depends on two independent dimensions, keep those dimensions
|
||
explicit rather than presenting a flattened list. Weapon definitions configure
|
||
one shared set of five Weapon Mod slots for T1 and T2. T0 uses the same set
|
||
minus one explicitly selected slot. A T2-native weapon shows only its applicable
|
||
shared-slot control, and tiers below the native tier remain unavailable.
|
||
Operators may save an unverified shared set or T0 exclusion when they cannot
|
||
inspect the weapon in-game. Mark an active weapon `CONFIG REQUIRED` until every
|
||
available tier has its full slot count, and keep verified assignments editable.
|
||
Reject unknown slot types and counts above the tier limit. Weapon Mod
|
||
definitions then configure one slot plus one or more compatible weapon
|
||
categories. The UI and validation must require both dimensions to match once the
|
||
weapon definition is complete.
|
||
|
||
Weapon Mod definitions use the shared segmented-choice control for the bounded
|
||
eight-slot vocabulary, with a full-width row on desktop and two columns on
|
||
narrow screens. Weapon category compatibility uses the same control in checkbox
|
||
mode with weapon icons and retained accessible names. Show configured versus
|
||
required slot counts in text. Disabled tiers remain visibly unavailable and must
|
||
not submit slot assignments.
|
||
|
||
Regular Weapon Mod definitions use a compact Level 1 and Level 20 primary-range
|
||
matrix for Standard, Specialized, Superior, and High-end quality. Apply global
|
||
quality colors only to the quality labels, retain textual quality names, and
|
||
keep numeric fields neutral. On narrow screens the matrix may scroll
|
||
horizontally while its surrounding editor and previews stack. Primary core type
|
||
remains builder-selected and appears as the three always-available core icons
|
||
rather than a persisted ISAC choice. Individual regular Weapon Mod editors also
|
||
retain triggerless Mod Effects with one or two Attribute references and fixed
|
||
per-quality values.
|
||
|
||
Configure one global secondary Attribute pool above the Weapon Mod registry.
|
||
Each repeatable row contains one searchable Attribute reference and Level 1 and
|
||
Level 20 minimum and maximum fields for Specialized, Superior, and High-end.
|
||
Values between those endpoints use linear interpolation. Do not render Standard
|
||
range fields because Standard has no secondary slot. State the fixed capacity in
|
||
the pool editor and builder: Standard zero, Specialized one, Superior two, and
|
||
High-end two. The builder requires distinct selections. Individual Weapon Mod
|
||
editors must not repeat or submit pool data. A successful pool save uses the
|
||
standard shared-profile lifecycle and creates the dedicated
|
||
`game_data/weapon_mod_secondary_pool.updated` audit event.
|
||
|
||
Exotic Weapon Mod status is a separate single-icon toggle using the exotic icon
|
||
and the standard pressed, focus-visible, and selected states. Selecting it must
|
||
switch the editor immediately, before a weapon is assigned. Exotic is its own
|
||
unique quality: reveal only the required exotic-weapon assignment, remove
|
||
weapon-category and regular-quality controls, and replace random ranges with
|
||
fixed level-1 and level-20 attribute values. Keep an explicit Exotic Quality
|
||
state panel visible so the change in data semantics is unmistakable.
|
||
|
||
### Gear Mod registry
|
||
|
||
Gear Mods reuse the compact Level 1 and Level 20 primary-range matrix and level
|
||
preview established by regular Weapon Mods. Do not render exotic,
|
||
weapon-category, slot-type, or Mod Effect controls in this simpler editor.
|
||
Present the five primary options as an always-visible informational band because
|
||
the build instance selects the primary; the canonical definition does not store
|
||
that selection.
|
||
|
||
Configure the Gear Mod family’s global secondary Attribute pool above the
|
||
registry, separate from individual Gear Mod editors. Use the same three-quality
|
||
endpoint rows, linear interpolation, and distinct-selection rule as the Weapon
|
||
Mod pool. Capacity is zero for Standard, one for Specialized, and two each for
|
||
Superior and High-end. Individual Gear Mod edits must not repeat or submit this
|
||
pool. A successful pool save creates the dedicated
|
||
`game_data/gear_mod_secondary_pool.updated` audit event.
|
||
|
||
Use explicit textual tier capacity wherever Gear tier is summarized:
|
||
`1 MOD SLOT` for T0 and `2 MOD SLOTS` for T1/T2. On narrow screens the identity
|
||
band and preview controls stack, while repeated quality data may scroll rather
|
||
than compressing numeric controls below usable sizes.
|
||
|
||
### Deferred game-data icons
|
||
|
||
Game-data icons are optional enrichment, never a blocker for creating or
|
||
proposing a canonical item. Upload fields must state that an icon may be
|
||
contributed later and show the shared `/missing-item-icon.svg` artwork when no
|
||
upload exists. Registries, relationship rails, and builder selection controls
|
||
use the same placeholder instead of initials, empty boxes, or ad hoc glyphs.
|
||
Application code references that asset through the shared
|
||
`MISSING_ITEM_ICON_URL` constant and renders it through `ItemIcon`; do not
|
||
duplicate its path or introduce module-specific missing-icon artwork.
|
||
|
||
Treat the placeholder as an explicit incomplete-data state: keep its subdued SHD
|
||
styling and useful alternative text where the surrounding item name is not
|
||
already available. Do not persist placeholder metadata or copy the placeholder
|
||
into per-item storage. A later contributor replaces it through the normal icon
|
||
upload proposal, preserving the canonical record and audit history. The upload
|
||
itself retains all transparent-format, size, SVG-safety, focus, drag/drop, and
|
||
paste validation requirements.
|
||
|
||
### Public database performance facts
|
||
|
||
Use the shared `DatabaseFacts` renderer for registry-card performance data and
|
||
quick views. Weapon identity headers keep the native tier beside the category
|
||
identity as a compact textual `T0`, `T1`, or `T2` marker. Place tier and the
|
||
smaller damage-type icon in a dedicated top-right status cluster; do not
|
||
interrupt the readable `category // damage type` metadata with icons. Reserve
|
||
the emphasized first fact for the weapon's damage range, pair it with the
|
||
canonical damage-type icon, and render the calculated level as a subdued
|
||
annotation rather than part of the primary label. Public level-50 damage must be
|
||
calculated from the stored level-1 endpoints with `weaponBaseRange`; never
|
||
relabel raw source values.
|
||
|
||
Represent bounded handling values such as Accuracy and Stability with compact
|
||
horizontal meters. Always retain the numeric value and an accessible
|
||
`value out of 100` label so the graphic does not carry meaning alone. Use the
|
||
stable sequence `label → meter → exact value`, with the exact number aligned in
|
||
a dedicated column to the right of the graphic. Clamp display values to `0–100`,
|
||
use orange only for the filled measure, and keep the unfilled track neutral.
|
||
Stack meter labels and tracks on narrow cards rather than shrinking them below a
|
||
reliably readable width.
|
||
|
||
Talent registry cards treat the two tier descriptions as their primary content;
|
||
never replace them with configured/missing summary facts. Render Tier I and Tier
|
||
II as distinct structured data blocks, then place mechanics metadata below both
|
||
descriptions. Use 16px semibold sans-serif text for tier effects so players can
|
||
scan them before supporting facts. Do not use the serif, quote-like prose
|
||
treatment. Use compact fixed tier labels and engineered borders. Tier I is the
|
||
neutral baseline; Tier II uses the orange rail, label, and subtly elevated
|
||
surface to communicate that it is the improved version. Render duration and
|
||
stack limits as detail rows with activation and cooldown data. Keep calculation
|
||
effects out of public Talent cards because the tier descriptions already state
|
||
the player-facing values. Omit a stack limit of one because a single active
|
||
instance is the default. The top-right header status uses the applicable
|
||
Backpack or Body Armor icon for gear talents and the SMG icon as the generic
|
||
Weapon Talent symbol. Weapon Talent headers pair that icon with an explicit
|
||
`1 · TOP` or `2 · BOTTOM` status badge; never rely on the slot number alone.
|
||
|
||
End each Talent card with a compatibility action. Gear Talent actions navigate
|
||
to the Gear registry with the Talent filter selected. Weapon Talent actions
|
||
navigate to the Weapons registry with the Talent Pool filter selected. Keep this
|
||
action in shared cards and relationship quick views so both contexts use the
|
||
same destination and label.
|
||
|
||
When a public registry needs only one small bounded filter vocabulary, use the
|
||
compact facet-panel form: one full-width group with all options visible in a
|
||
single row on wide screens. Talent slot filtering uses Backpack, Body Armor,
|
||
Weapon 1 · Top, and Weapon 2 · Bottom. Always include the Top/Bottom context
|
||
when presenting numbered Weapon Talent slots to users. The filter remains
|
||
additive within the group and wraps to two columns on narrow screens; do not
|
||
introduce search or dropdown controls for this four-option set.
|
||
|
||
Notification delivery preferences are a temporary profile control surface. After
|
||
a successful save, close the interface and return focus to the inbox context.
|
||
Consume a unique server result token only once so later actions or reopening the
|
||
panel do not close it again. Validation and server errors keep the interface
|
||
open with the submitted controls available for correction.
|
||
|
||
### Global toast feedback
|
||
|
||
Use the root-mounted `ToastViewport` and the shared API in `src/lib/toast.ts`
|
||
for transient action feedback. Enhanced server mutations should normally use
|
||
`PendingForm`, which derives success and failure feedback from the action
|
||
result. Client-only operations call `toast.success`, `toast.error`,
|
||
`toast.warning`, or `toast.info` directly. Do not create page-specific toast
|
||
implementations.
|
||
|
||
Toasts occupy the top-right safe area below the global header and show no more
|
||
than four messages. Each uses a textual state label, tone-colored top and left
|
||
rails, a concise title, optional supporting text, and an explicit dismiss
|
||
control. Success is green, errors use danger red, warnings use SHD orange, and
|
||
informational feedback uses restrained blue-gray. Color never carries state
|
||
alone.
|
||
|
||
Use success to confirm completed mutations, error for failed requests, warning
|
||
when attention is required, and info for neutral client or system state. Keep
|
||
inline validation beside affected fields even when an error toast is also
|
||
emitted. Avoid toasts for passive navigation, filtering, hover, unpersisted
|
||
selection changes, and background refreshes. Toasts automatically dismiss
|
||
according to severity, remain keyboard dismissible, use `status` or `alert`
|
||
semantics, and disable entrance motion with reduced motion. On mobile they span
|
||
the safe viewport width below the header without obscuring navigation.
|
||
|
||
### ISAC progressive disclosure
|
||
|
||
The ISAC rail shows every module the current operator is authorized to access,
|
||
but groups modules behind collapsible operational categories. The category
|
||
containing the current route opens on first use; subsequent open and closed
|
||
choices are remembered locally for that browser. Searching the rail temporarily
|
||
reveals matching modules across all authorized categories without changing the
|
||
remembered category state.
|
||
|
||
Use the compact command-status strip for persistent system, access, ISAC node,
|
||
and CI build number context. Add the data-mode cell only in the Data Management
|
||
context defined above. Keep each label above its value so the visible cells
|
||
share one alignment. Text must communicate every state without relying on color.
|
||
Registry search remains available for a single page of results, while page
|
||
navigation and row-count controls appear only when the result set spans multiple
|
||
pages. This keeps expert lookup fast without presenting inactive controls to
|
||
contributors and first-time Oversight operators.
|
||
|
||
Sidebar category headers are real buttons with `aria-expanded` and controlled
|
||
navigation regions. Search fields have visible or accessible labels, keyboard
|
||
focus uses Signal Orange, and collapsed state must remain understandable without
|
||
motion.
|
||
|
||
### Managed image library
|
||
|
||
Reusable uploaded visuals belong in the ISAC Image Library under System
|
||
Configuration. Present assets as a dense responsive registry of preview cards:
|
||
the artwork is primary, while name, assignment category, tags, dimensions, and
|
||
file size remain compact operational metadata. A checkerboard preview surface
|
||
may make transparency legible without changing the asset.
|
||
|
||
Image intake uses the shared picker, drop-zone, and clipboard control. The
|
||
`Normalize as icon` option trims transparent outer margins and standardizes the
|
||
canvas. When the source has no usable transparency, the server requests
|
||
preview-resolution background removal before local normalization and reports
|
||
configuration, credit, rate-limit, foreground-detection, or network failures
|
||
with a specific recovery. Its dependent `Force white` option converts visible
|
||
pixels to the canonical neutral icon color while preserving alpha. Both controls
|
||
state their processing consequence in text, expose checked and disabled states,
|
||
and remain keyboard accessible. Metadata edits preserve the stable asset
|
||
identity, close after a successful save, and use the shared toast and editor
|
||
lifecycle.
|
||
|
||
Use controlled assignment categories for broad placement and free-form,
|
||
normalized tags for discovery. Names are unique and human-readable. Search
|
||
covers names, categories, and tags. On narrow screens, processing controls stack
|
||
vertically and cards reduce to one column so previews and actions retain usable
|
||
sizes.
|
||
|
||
### ISAC mutation consequence
|
||
|
||
Every writable game-data module states what Save will do before the operator
|
||
opens an editor, and the statement remains visible while the editor is open. The
|
||
message is derived from effective permissions rather than copied into each
|
||
module:
|
||
|
||
- `OVERSIGHT REVIEW` means saving creates a proposal and does not change live
|
||
data until Oversight approves it.
|
||
- `DIRECT PUBLISH` means the change becomes live immediately and creates an
|
||
append-only audit event.
|
||
|
||
Pair the short state label with a complete consequence sentence. Contributors
|
||
must not have to infer this behavior from their role name, data-mode color, or a
|
||
success message shown after saving. Read-only operators do not see a mutation
|
||
statement because their mutation controls are absent. At narrow widths the
|
||
message becomes its own compact row above the module toolbar. A toolbar with
|
||
multiple actions must reserve the complete action group width in the inline
|
||
desktop strip so the consequence sentence never runs beneath a button.
|
||
|
||
### Public database index
|
||
|
||
The public Database is a lookup surface first and a contribution gateway second.
|
||
Use a compact angular command band rather than a cinematic display hero: keep
|
||
the archive identity, state how many registries are online, state the record
|
||
total, and present contribution as a bordered secondary action.
|
||
|
||
Place one discovery bar below the command band. Its label gives users two equal
|
||
paths: select a registry or search all data. Its search field searches across
|
||
all public registry names and useful descriptive data such as Talent text,
|
||
Damage Types, item slots, qualities, and Brand bonus Attributes. Do not stack a
|
||
separate registry-heading bar above or below it. Results name both the matching
|
||
record and its registry, then link into that registry with the record name
|
||
applied as its local search. Keep the search and results dense, keyboard
|
||
accessible, responsive, and URL-addressable.
|
||
|
||
Registry selection begins immediately after the shared discovery bar. Do not
|
||
place stewardship, status, promotional, or redundant instructional panels
|
||
between it and the registry grid. At wide desktop widths, eight registries form
|
||
a four-by-two matrix; the grid reduces to two columns and then one as available
|
||
space narrows. Registry cards lead with complete category names. Counts and
|
||
availability remain quiet footer metadata, and internal abbreviations or
|
||
workflow-centric states are not exposed as primary public labels.
|
||
|
||
### ISAC progression-tree composer
|
||
|
||
Use the Specialization workbench pattern for ordered game systems that depend on
|
||
hierarchy and spatial placement. Keep the registry, selected parent identity,
|
||
child navigation, readiness telemetry, and visual tree in one operational
|
||
surface. Editors open above the registry and follow the standard ISAC lifecycle.
|
||
Use the workbench for navigation and context.
|
||
|
||
The tree uses a stable 12-column track per row. Row and column are explicit
|
||
numeric fields so placement is keyboard operable, auditable, and portable; never
|
||
make drag-and-drop the only authoring method. On narrow screens, retain the
|
||
geometry in a horizontally scrollable canvas instead of squeezing nodes until
|
||
their names and state are unreadable. Controls outside the canvas stack and
|
||
maintain at least a 44-pixel touch target.
|
||
|
||
Each row header states its derived gate in plain language. Specialization gates
|
||
count all available Rank 1 and Rank 2 unlocks in preceding rows, including the
|
||
two immediately available ability nodes displayed in the first row. Do not store
|
||
or manually edit a second gate value that could diverge. Free nodes use the
|
||
orange identity rail plus the explicit `1 / 1 · FREE` state; pending, archived,
|
||
incomplete, and builder-ready states must remain textual as well as colored.
|
||
|
||
Show allocation scope as first-class telemetry. A specialization unlocks once;
|
||
each focus receives its own full point allocation. Show the point total and
|
||
scope near the tree. A focus becomes builder-ready after it has three distinct
|
||
active abilities, each ability has exactly three active Skill Chip definitions,
|
||
tree rows are contiguous, at least one paid node exists, and the tree uses the
|
||
configured available point total.
|
||
|
||
The ability editor may pair the open ability with one active ability from the
|
||
same specialization for Skill Chip sharing. Present this as an explicit optional
|
||
relationship, exclude the current ability, and disable abilities that already
|
||
belong to another pair. Do not infer compatibility from names or Focus
|
||
membership. Saving either side updates the shared pair and includes it in the
|
||
ability audit snapshot. Archiving either ability clears the pair.
|
||
|
||
Compose focus identity from uploaded specialization artwork and the canonical
|
||
Firepower, Toughness, or Engineering icon. Keep the specialization art primary
|
||
and place the attribute mark in a smaller corner badge. Mirror ability slots 1
|
||
and 3 as free tree nodes. Label slot 2 Combat Skills-only and exclude it from
|
||
the upgrade tree. Universal grenade and medical-kit actions are outside the
|
||
specialization ability set.
|
||
|
||
Use `StructuredEffectEditor` whenever an ISAC record needs an ordered set of
|
||
calculation-ready effects. It provides Attribute, Ability when applicable, and
|
||
Custom targets; a numeric value; and the shared bounded unit vocabulary. Keep
|
||
the target searchable, show all bounded type and unit choices with segmented
|
||
controls, and preserve explicit custom labels for mechanics that calculations do
|
||
not yet support. Oversight previews must render effect and rank summaries as
|
||
structured cards. Serialized JSON belongs only in the expandable raw-evidence
|
||
panel.
|
||
|
||
Exclusive child-record relationships use a searchable assignment block directly
|
||
after the record identity. The header names the parent type, states the
|
||
relationship and capacity in plain language, and shows current usage as `N / N`.
|
||
The registry repeats the assigned parent beside each child so exclusivity can be
|
||
audited without opening the editor. Records that require an exclusive parent
|
||
must always have a valid active assignment. Capacity rules are enforced on the
|
||
server and never communicated by color alone.
|
||
|
||
Rank cards present the complete rank description, structured effects, point
|
||
cost, Credits, and material cost together. Specialized Alpha, Beta, and Gamma
|
||
components use the shared blue quality treatment and may be combined in any
|
||
positive whole-number quantities for Rank 2. Rank 3 uses the yellow High-end
|
||
Omega treatment and exactly one component. Color is supporting hierarchy;
|
||
quality names and quantities always remain visible.
|
||
|
||
### Source-owned mechanic program editor
|
||
|
||
Use `MechanicProgramEditor` for every calculation-ready standard or exotic
|
||
Talent, OS Protocol Talent, Skill Chip Talent, and Specialization tree-rank
|
||
effect. The program stays inside its owning source editor and contribution
|
||
payload. Do not create a standalone Trigger registry, Trigger assignment
|
||
control, or shared Trigger lifecycle.
|
||
|
||
Each source supplies the value columns required by its progression:
|
||
|
||
- Standard Talents show Tier I and Tier II. Exotic Talents show Tier I and an
|
||
explicit Tier II documentation state; the editor adds the Tier II value column
|
||
only when contributors select `DOCUMENTED`.
|
||
- OS Protocol Talents show a base value and may scale an outcome through the
|
||
protocol's zero-to-five upgrade expression.
|
||
- Skill Chip Talents show minimum and maximum values.
|
||
- Specialization tree ranks show the rank's base value.
|
||
|
||
The editor is one layered control surface. Start with a compact program heading
|
||
and the explicit `READY`, `REQUIRES ASSUMPTIONS`, or `CAPTURED ONLY` state.
|
||
Follow it with Builder Controls, Recipe Starter, State Pools, ordered event
|
||
branches, ordered outcomes, and the generated read-only script. Use connected
|
||
panels and restrained borders to preserve the hierarchy; do not present the
|
||
typed graph as an undifferentiated form.
|
||
|
||
Talent editors place that surface inside the shared `modeling-disclosure`
|
||
pattern. New `CAPTURED ONLY` Talents start with an empty program and a collapsed
|
||
`COMBAT MODELING` summary so authors can record identity, image, and source
|
||
description first. Existing modeled Talents open the disclosure when edited.
|
||
Mechanic validation errors open it and keep the relevant error text visible. The
|
||
summary reports `CAPTURE ONLY · MODEL LATER` or the configured branch count in
|
||
text. Its native disclosure semantics preserve keyboard and assistive technology
|
||
support; mobile targets remain at least 44 pixels tall.
|
||
|
||
The direct-event picker reads the 28 normalized events from the code-defined
|
||
event registry. Use searchable single-assignment because the vocabulary exceeds
|
||
the compact segmented-choice limit. Each branch presents its event, match policy
|
||
and parameters, optional cooldown, condition, state mutations, and outcomes. The
|
||
branch condition offers `ALWAYS`, `HEALTH BAND`, `EVENT FIELD`, and
|
||
`STATE THRESHOLD` for manual authoring. When the selected event publishes field
|
||
metadata, event-field conditions derive their available paths and scalar types
|
||
from that metadata. Events without a bounded field contract retain the explicit
|
||
field-path and value-type controls. Event-field conditions expose the comparison
|
||
operator and typed value. State thresholds compare an agent-scoped pool with a
|
||
numeric value. Health bands expose an optional inclusive lower Health percentage
|
||
and a required exclusive upper percentage; helper text states how exact
|
||
thresholds resolve. Predicates outside these manual patterns remain preserved,
|
||
display `ADVANCED`, and stay visible in the generated script. State rows expose
|
||
label, agent or target scope, initial value, bounds, best-case value, and
|
||
optional expiry. A state change that writes a target pool uses a `STATE OWNER`
|
||
segmented control with `EVENT TARGET` and `EVENT ACTOR`; the selected owner
|
||
remains visible in the generated script. The `DERIVED VALUE` operation writes
|
||
the branch reducer's numeric result into the selected pool and displays that
|
||
link as a text readout instead of a numeric input. Outcome rows expose kind,
|
||
target scope, Attribute or resource when applicable, value basis, state scaling,
|
||
phase, and every source-specific value column. The Value Model control supports
|
||
values, live Attribute totals, percentage-normalized Attribute values, event
|
||
fields, reducer output, source-defined scenario controls, and OS Protocol
|
||
upgrade scaling where the source permits it. Selecting either Attribute model
|
||
uses the shared searchable single-assignment pattern and displays the
|
||
Attribute's unit. Label the direct model `LIVE ATTRIBUTE`. Label the
|
||
percentage-normalized model `ATTRIBUTE ÷ 100` so authors can see the transform
|
||
applied to the stored value. Restoration outcomes also expose an `INSTANT` or
|
||
`CONTINUOUS` segmented choice. Continuous delivery reveals one required duration
|
||
field and describes the configured value as the total delivered across that
|
||
duration; switching back to instant clears the duration.
|
||
|
||
Selecting `DERIVE A SCALAR VALUE` exposes a `DERIVED VALUE SOURCE`
|
||
`SegmentedChoice`. `STATIC` shows the numeric value input. `EVENT FIELD` shows
|
||
the numeric fields registered for the branch event, including the proximity
|
||
snapshot's allied-Agent count; it never asks the author to type a field path.
|
||
Keep an existing expression that falls outside these manual patterns visible as
|
||
disabled `ADVANCED` data. The source and field controls retain `SegmentedChoice`
|
||
radio semantics, visible legends, arrow-key operation, focus-visible treatment,
|
||
and text labels.
|
||
|
||
Target-scoped direct-damage outcomes offer `HIT-TARGET EXPLOSION` in the Area
|
||
Targeting control. Selecting it creates an event-target-centered enemy area with
|
||
a five-meter starting radius, reveals the required radius field, and shows a
|
||
text readout for the center, valid-target policy, inclusive boundary, and
|
||
runtime evidence requirement. Only `ON EVENT` and `AFTER EVENT` remain available
|
||
for this mode; selecting it from another phase moves the outcome to
|
||
`AFTER EVENT`. Changing the outcome kind or target scope clears an incompatible
|
||
area definition. Keep `ENEMIES IN RADIUS · LEGACY` visible for saved descriptive
|
||
radius metadata, but do not present that mode as calculated explosion fan-out.
|
||
|
||
Action Family recipes are optional authoring starters. Present the recipe
|
||
catalog as a searchable assignment with only the parameters required by the
|
||
selected family. `ADD RECIPE BRANCH` copies typed branches into the current
|
||
source program, where authors may edit its exposed branch, state, and outcome
|
||
controls. The recipe label records provenance only. `REPLACE PROGRAM` requires
|
||
an inline confirmation that states all existing branches will be discarded.
|
||
|
||
Builder Controls define source-specific scenario assumptions for player
|
||
simulation. ISAC authors choose toggle, slider, or numeric input and provide a
|
||
label, Agent guidance, default value, best-case value, and numeric bounds when
|
||
applicable. The calculation timeline builder can consume values supplied for
|
||
these controls, including `allies-within-30m-with-agent-granted-buff`. Current
|
||
Builder and shared Build pages do not render the controls or let players change
|
||
those values. They use an explicit `COMING SOON` panel for the future advanced
|
||
scenario surface. The authored contract still requires the runtime to report
|
||
`REQUIRES ASSUMPTIONS` when a required cadence or environmental value is
|
||
missing; the editor and runtime never invent a cadence.
|
||
|
||
Use `--shd-model-surface` and `--shd-model-border` for mechanic programs,
|
||
calculation revisions, and field calibration. The blue information rail marks
|
||
modeled behavior. Orange remains reserved for selection and activation. Name
|
||
events, branches, state, cooldowns, durations, stack limits, outcomes, phases,
|
||
and per-stack values in text so the model remains legible without color.
|
||
|
||
At narrow widths, stack panels, branch controls, state rows, variant columns,
|
||
and outcomes without changing their order. Keep add, remove, replace, and help
|
||
controls at least 44 pixels tall. Every disclosure and confirmation exposes its
|
||
state to assistive technology. Focus remains in the active field when the
|
||
generated script refreshes, and reduced-motion preferences remove expansion and
|
||
replacement transitions.
|
||
|
||
The recipe starter opens with no recipe selected. Keep its count, duration,
|
||
distance, and Health-band parameters hidden until the author chooses a recipe.
|
||
Health-band recipes expose ordered strict upper thresholds and editable band
|
||
labels. Stack each band row on narrow screens and keep its remove action at
|
||
least 44 pixels tall. Disable `ADD RECIPE BRANCH` while the selection is empty,
|
||
and show `REPLACE PROGRAM` only after the author selects a recipe and the
|
||
current program contains a branch.
|
||
|
||
#### AI mechanic drafting
|
||
|
||
`MechanicProgramEditor` keeps its complete manual authoring controls available
|
||
to every authorized data author. Place the optional AI drafting panel inside
|
||
that editor, after the source description and before the structured mechanic
|
||
controls. AI assistance must never replace, hide, lock, or reset the manual
|
||
workflow.
|
||
|
||
The panel uses one compact modeled-data surface with a blue information rail.
|
||
Its heading names `AI MECHANIC DRAFTING` and identifies the output as a draft.
|
||
An author submits the exact in-game mechanic text and optional context. Keep the
|
||
source text editable during clarification and preview. Use the standard pending
|
||
button treatment while a request runs and block duplicate submissions.
|
||
|
||
Agents without `ai.mechanic.generate` still see the collapsed panel. Disable its
|
||
request control, label the state `PERMISSION REQUIRED`, and direct the agent to
|
||
request permission from an administrator. The disabled state must not expose API
|
||
configuration, internal prompt content, model controls, or a working form
|
||
submission.
|
||
|
||
The panel presents five explicit states:
|
||
|
||
- `READY FOR INPUT` shows the source-text field and Generate Draft action.
|
||
- `DRAFTING` keeps the submitted text visible, announces progress through a
|
||
polite live region, and disables repeat actions.
|
||
- `CLARIFICATION REQUIRED` lists each focused question with its reason and
|
||
bounded answer control. The author may answer, revise the source text, or
|
||
return to manual authoring. For an unresolved numbered numeric placeholder,
|
||
show a required clarification for every source value column whose number is
|
||
missing. Do not prefill, infer, or suggest a percentage. Keep
|
||
`APPLY TO EDITOR` unavailable until the author answers each required variant.
|
||
- `CAPABILITY GAP` names the unsupported behavior and displays the developer
|
||
handoff, supported approximation, and optional workaround in separate labeled
|
||
blocks. Do not present a capability gap as validation failure.
|
||
- `DRAFT PREVIEW` shows assumptions, warnings, readiness, and the generated
|
||
script before an explicit `APPLY TO EDITOR` action.
|
||
|
||
The capability-gap state offers `COPY DEVELOPER PROMPT` and
|
||
`SUBMIT TO ADMIN TEAM` beside `REVISE SOURCE WORDING`. The copied prompt
|
||
includes the exact analyzed wording, clarification answers, gap evidence, and
|
||
implementation acceptance criteria. Submission sends one mandatory ISAC
|
||
notification to each active full administrator and records the report in the
|
||
`ai_assistance` audit history. Disable duplicate submission for the current
|
||
assistant request. Clipboard or network failures keep the handoff visible and
|
||
show a specific recovery message. Neither action changes the mechanic editor or
|
||
saves the parent record.
|
||
|
||
Applying a draft fills the structured fields in the current unsaved editor. It
|
||
does not save, publish, submit a proposal, close the editor, or discard manual
|
||
changes without confirmation. Show a concise before-and-after summary when
|
||
applying the draft would replace configured branches, pools, controls, or
|
||
outcomes. The standard ISAC save lifecycle begins only after the author reviews
|
||
and saves the resulting form.
|
||
|
||
An applied AI draft stores each clarified number in the corresponding
|
||
human-facing outcome-variant value. A scaling expression may retain the
|
||
draft-only `variant_value` reference so later saves preserve the link to that
|
||
displayed value. The runtime adapter resolves the reference separately for each
|
||
variant. Show the value and generated formula in the ordinary review controls;
|
||
do not require an author to inspect or edit raw JSON.
|
||
|
||
Use text labels with status colors. Orange marks Generate, Answer, and Apply
|
||
actions. Blue identifies modeled information, yellow marks assumptions or
|
||
unsupported coverage, and red marks request or validation failures. Never use
|
||
model confidence as the only acceptance signal.
|
||
|
||
On narrow screens, stack questions, answers, preview metadata, and actions in
|
||
source order. Keep controls at least 44 pixels tall and keep the draft preview
|
||
inside the viewport. Focus moves to the first clarification question, the
|
||
capability-gap heading, or the draft-preview heading when a result arrives.
|
||
Return focus to the initiating control when the author closes or resets the
|
||
panel. Announce the result state without reading the complete generated script.
|
||
Reduced-motion preferences remove pending, disclosure, and preview transitions
|
||
while preserving textual state changes.
|
||
|
||
#### Generated mechanic script
|
||
|
||
The shared `PseudoScript` component gives authors and builders a readable
|
||
transcription of the typed mechanic or combat calculation. The typed event,
|
||
predicate, reducer, state-pool, outcome, and calculation-stage data remain
|
||
authoritative. The interface generates the script from that data; authors do not
|
||
edit or execute the displayed text.
|
||
|
||
Render generated script on `--shd-model-surface` with `--shd-model-border`, a
|
||
blue information rail, restrained green syntax keywords, line numbers, and the
|
||
shared monospaced typeface. Give the panel an explicit
|
||
`GENERATED SCRIPT · READ ONLY` label and show its calculation readiness in text.
|
||
Reserve orange for adjacent actions and selected controls. Do not style the
|
||
panel as an editable textarea or show a caret, resize handle, or save action.
|
||
|
||
Use semantic code content inside the panel. Treat line numbers as structural
|
||
decoration and ensure assistive technology reads each statement once. Preserve
|
||
indentation and keep type at the telemetry floor. Long statements may wrap at
|
||
token boundaries or use horizontal scrolling on narrow widths. Keep the panel
|
||
within its parent grid with `min-width: 0`. Script regeneration must not move
|
||
focus or announce the complete script after each field change. Place validation
|
||
and readiness messages beside the panel with ordinary status semantics.
|
||
|
||
Use the shared `MechanicLanguageHelp` control wherever an author can configure
|
||
mechanics or calculation stages. The compact `SCRIPT REFERENCE` button opens a
|
||
native help dialog with syntax, event, timing, state, and outcome references.
|
||
Long registry-level references may use a labeled disclosure with the same
|
||
content. The help trigger remains near the generated preview so authors do not
|
||
need to leave the editor to interpret it. Point every full-reference action to
|
||
`/isac/mechanic-reference`, with a stable section anchor when the source has a
|
||
specific topic. Do not point full-reference actions to collapsed same-page
|
||
anchors.
|
||
|
||
Help triggers and disclosure summaries use native button semantics,
|
||
focus-visible treatment, and explicit expanded or dialog state. Opening a dialog
|
||
moves focus to its close control; Escape and the close action dismiss it and
|
||
return focus to the trigger. On mobile, the dialog fits the viewport, scrolls
|
||
its body, and keeps its close action available. Reduced-motion preferences
|
||
remove dialog and disclosure transitions. Syntax color and motion never carry
|
||
meaning without text.
|
||
|
||
#### Mechanic reference surface
|
||
|
||
`/isac/mechanic-reference` is the dedicated read surface for the mechanic and
|
||
combat-calculation languages. It contains no mutation controls. Give the page a
|
||
compact section index beside the reference body and keep that index sticky when
|
||
the available width and viewport height support it. Assign a stable heading
|
||
anchor to each major section so editor dialogs can link to the relevant
|
||
definition.
|
||
|
||
Present bounded syntax, state, phase, outcome, and calculation-stage
|
||
vocabularies as connected reference matrices with shared borders and aligned
|
||
columns. Generate the event registry and Action Family recipe catalog from
|
||
code-defined metadata so the reference matches the available editor controls.
|
||
Explain that events are runtime contracts and recipes only seed editable source
|
||
branches. Pair complex mechanics with a worked `PseudoScript` example. Keep
|
||
labels and descriptions visible; color, abbreviations, and script keywords
|
||
cannot carry the explanation alone.
|
||
|
||
Include a live-searchable Attribute variable glossary sourced from the active
|
||
ISAC Attribute registry. Search matches Attribute names, stored descriptions,
|
||
types, categories, calculation types, units, source ranges, and caps. Display
|
||
each stored Attribute description verbatim. Show type, category, calculation
|
||
type, unit, applicable Gear, Weapon, and Skill Chip ranges, and optional cap as
|
||
supporting metadata. Mark a missing description as `DOCUMENTATION NEEDED` and
|
||
link authorized authors to the Attribute record; do not generate substitute
|
||
copy. Search operates on the full active glossary before any result limit and
|
||
keeps its visible label, clear action, keyboard focus, and textual result count.
|
||
|
||
Section-index links and anchored headings use visible keyboard focus. In-page
|
||
navigation must place the target below the application header. At narrow widths,
|
||
move the index into document flow above the content and stack reference sections
|
||
in one column. Allow connected matrices to scroll within their own boundaries,
|
||
and prevent horizontal page overflow. Reduced-motion preferences remove smooth
|
||
anchor scrolling and sticky-state transitions.
|
||
|
||
#### Builder calculation modes
|
||
|
||
The current Builder and shared Build pages do not expose calculation modes or
|
||
combat assumptions. They show deterministic equipped-item totals and reserve
|
||
conditional Talent outcomes, weapon and Skill DPS, encounter assumptions,
|
||
activation profiles, rotations, and simulation behind explicit `COMING SOON`
|
||
panels.
|
||
|
||
Loadout schema version 6 retains `maximum`, `custom`, conditional state,
|
||
encounter-assumption, and per-ability activation fields. Version 4 is obsolete
|
||
prototype data rather than a compatibility format. The current player UI ignores
|
||
the simulation fields. When player simulation ships, one required two-option
|
||
`SegmentedChoice` will use these visible labels:
|
||
|
||
- `MAXIMUM POTENTIAL` calculates a configured ceiling. It applies conditional
|
||
effects at peak state and treats selected abilities as firing on cooldown
|
||
against their maximum configured target count.
|
||
- `CUSTOM SCENARIO` exposes encounter assumptions and source-defined advanced
|
||
controls for a player-defined scenario.
|
||
|
||
The planned interface selects `MAXIMUM POTENTIAL` for new loadouts and labels
|
||
its results as a modeled ceiling. Maximum will hide granular assumption fields
|
||
without deleting their saved values. Returning to Custom will restore those
|
||
values.
|
||
|
||
The planned Custom mode gives each unlocked conditional effect three state
|
||
controls:
|
||
|
||
- `OFF` excludes the effect.
|
||
- `PEAK` applies its configured maximum stacks.
|
||
- `ENCOUNTER` models stack buildup and expiry from weapon RPM, magazine size,
|
||
reload time, hit rate, firing activity, and encounter duration.
|
||
|
||
The planned advanced scenario surface will let users override one effect without
|
||
changing the global Custom profile. It will show only the toggle, slider, and
|
||
numeric controls defined by that effect's owning source. The effect card will
|
||
show uptime, activation count, and applied stack state beside the mode. A
|
||
mechanic that needs an undefined cadence or another missing scenario input will
|
||
display `REQUIRES ASSUMPTIONS`; the simulation will withhold its contribution
|
||
until the author or player supplies that input.
|
||
|
||
The future Maximum and Custom control will use radio semantics, an explicit
|
||
selected label, keyboard arrow navigation, and the standard orange selected
|
||
rail. Results will repeat the active calculation mode in text. On mobile, the
|
||
global mode control and Custom assumption fields will stack into full-width
|
||
targets of at least 44 pixels. Mode changes will use the standard pressed
|
||
feedback; reduced-motion preferences will remove transitions without hiding the
|
||
state change.
|
||
|
||
The future combat result panels will show normal, critical, headshot, and
|
||
critical-headshot values with burst, sustained, and encounter DPS. Conditional
|
||
stack telemetry will list the mode, uptime, activations, average and peak
|
||
stacks, ending stacks, buildup time, and maintained state. A result with missing
|
||
equipment, Attribute bindings, rules, or assumptions will display
|
||
`INSUFFICIENT DATA` and a concrete remediation list. Until this interface ships,
|
||
the player pages show `COMING SOON` instead of combat numbers.
|
||
|
||
### Specialization loadout composer
|
||
|
||
The builder presents Specialization and Focus as the first loadout decision. The
|
||
Focus sets the primary Attribute, progression tree, and three ordered abilities.
|
||
Its identity combines Specialization artwork and the primary Attribute mark.
|
||
Each ability panel contains three fixed Skill Chip positions. A chip picker
|
||
shows the ability's three definitions. When ISAC explicitly pairs that ability
|
||
with one compatible ability, the picker also shows the partner's three
|
||
definitions and labels shared entries. The relationship is bidirectional and
|
||
does not apply to other abilities in the same specialization. Players still
|
||
equip three chips in each ability panel. Skill Chips have no item-level control.
|
||
The editor uses the shared quality profiles for direct rolls. It labels the four
|
||
ability-scoped primary values `NOT YET DEFINED` and excludes them from current
|
||
Agent and combat totals. Shared-chip primary values and 3-piece Talent outcomes
|
||
target the ability represented by the panel. Secondary capacity is Standard
|
||
zero, Specialized one, Superior two, and High-end two; each equipped chip uses
|
||
distinct selections from the shared pool.
|
||
|
||
The focus tree groups nodes by row and uses segmented rank controls. Disabled
|
||
ranks remain visible with their lock state. The builder permits a row after the
|
||
user buys every available Rank 1 and Rank 2 in preceding rows and enforces the
|
||
49-point limit. Cost telemetry lists Credits and components beside each rank.
|
||
|
||
Player ability panels currently expose equipped definitions and deterministic
|
||
item contributions. Planned simulation panels display `COMING SOON` instead of
|
||
activation controls or Skill DPS. The future interface will offer Off, On
|
||
Cooldown, or Custom Rate, with uses per minute and a target count for each
|
||
enabled ability. Future Skill result cards will show activation count,
|
||
single-target DPS, total-target DPS, and a combined summary. They will state
|
||
that Skills can critically hit and multi-shot but cannot headshot.
|
||
|
||
Version 5 loadouts store focus, node ranks, nine Skill Chips, conditional modes,
|
||
encounter assumptions, and per-ability activation profiles. The builder accepts
|
||
only the current complete structure. Current player pages ignore the simulation
|
||
fields. The builder discards version 4 local drafts; a backed-up database
|
||
migration removes version 4 server records.
|
||
|
||
### Calculation revision controls
|
||
|
||
Combat rules use immutable active and retired revisions. ISAC editors may change
|
||
draft revisions, ordered stages, and Attribute profiles. Activation requires
|
||
`calculation.publish`, an explicit review state, and a confirmation that saved
|
||
builds will recalculate. Successful activation closes the confirmation surface
|
||
and records the revision in the audit history.
|
||
|
||
Keep weapon and Skill Attribute profiles in separate compact registries inside
|
||
the same revision editor. A Skill profile shows the Attribute, one of the
|
||
bounded Skill stages, Add or Multiply, and its weight. Use searchable assignment
|
||
for the ten-stage vocabulary and a segmented control for the two-value operator.
|
||
Reject duplicate Attribute and stage pairs. Revision cloning, proposal review,
|
||
publication evidence, and audit snapshots must include both profile registries.
|
||
|
||
Calibration cases pair a loadout snapshot with measured hit and timing values.
|
||
Ready cases require the four hit values, magazine time, and reload time.
|
||
Assisted suggestions create a draft revision for review and leave activation to
|
||
an authorized operator. Use monospaced text for raw loadout and prediction
|
||
snapshots; labels, findings, and errors stay in the standard operational
|
||
typeface.
|
||
|
||
Calculation revision editors include the optional AI drafting panel after the
|
||
revision identity and before the manual stage and profile controls. Reuse the
|
||
`READY FOR INPUT`, `DRAFTING`, `CLARIFICATION REQUIRED`, `CAPABILITY GAP`, and
|
||
`DRAFT PREVIEW` states from AI mechanic drafting. The panel uses calculation
|
||
language, identifies the active or edited base revision, and previews changes to
|
||
stages, weapon profiles, and Skill profiles.
|
||
|
||
ISAC keeps revision editing, calibration, assisted suggestions, publication, and
|
||
the calculation AI assistant available for continued model authoring. The
|
||
current Builder and shared Build pages do not consume their output.
|
||
|
||
Agents without `ai.calculation.generate` see the collapsed `PERMISSION REQUIRED`
|
||
state. Agents with the permission may request and apply a draft, but the panel
|
||
leaves every manual calculation control available. Applying a draft fills the
|
||
open unsaved revision form. It does not save the revision, activate it, grant
|
||
`calculation.publish`, or bypass the activation confirmation. Before applying,
|
||
show current and proposed counts for stages, weapon profiles, and Skill profiles
|
||
beside assumptions, warnings, and the generated script.
|
||
|
||
Use the same pending, duplicate-request, focus, live-region, mobile stacking,
|
||
44-pixel target, and reduced-motion rules as the mechanic assistant. A
|
||
calculation capability gap names the unsupported stage, operator, binding,
|
||
curve, or runtime behavior and keeps the manual revision editor available.
|
||
|
||
### Image Library assignment state
|
||
|
||
An ISAC game-data editor registers each uploaded icon in the Image Library. The
|
||
library record and editor share one processed file. Its card uses
|
||
`ASSIGNED ICON`, names the owning entity type beside the category, and carries
|
||
searchable tags for `isac`, `game data`, the module, the entity name, and entity
|
||
context such as quality, focus, ability, or Talent category.
|
||
|
||
Operators may rename, recategorize, and add tags to the library record.
|
||
Replacing the icon from its game-data editor keeps that metadata and refreshes
|
||
the context tags and file facts. Removing the source icon removes its linked
|
||
library record. Each library card offers `DOWNLOAD`, `EDIT`, and `DELETE` in a
|
||
connected action rail. `DELETE` opens a focused confirmation that names the
|
||
asset and states that the change is permanent. For assigned icons, the
|
||
confirmation names the owning entity type. ISAC clears that source icon
|
||
assignment before it removes the shared file. General library uploads retain the
|
||
`ICON` or `IMAGE` state.
|
||
|
||
In the Weapon Mod registry, operators manage shared artwork for all eight
|
||
code-defined slots. The compact panel labels each slot `ICON REGISTERED` or
|
||
`ICON REQUIRED`. Selecting a slot opens the standard icon upload control. Keep
|
||
the slot name visible in ISAC after an operator uploads artwork.
|
||
|
||
On public weapon cards, a configured slot chip shows only its uploaded icon.
|
||
Keep the slot name in screen-reader and hover text. Retain the visible `T1+`
|
||
marker and blue information treatment for slots unlocked at Tier 1. When artwork
|
||
is missing, show the slot name instead of an invented glyph.
|