Character kit

One 3D character, built from KayKit Adventurers parts (CC0) on a shared skeleton. It mirrors the user type set in Profile > User Type and takes its colours from the live theme, so it reads as part of the UI rather than as an illustration. Code: js/profile-persona-character.js (rendering) and js/profile-persona.js (user type to recipe).

Live specimen

The real module on this page. Pick parts or a profile; drag the figure to turn it. Switch Light / Dark in the menu, or pick a Multi-color theme in Profile > Theme, to see the recolour.

Drag to turn
Profile
Headwear · financial knowledge
Outfit · banking products
Back · banking products
Loop · digital affinity

      

Anatomy: slots and recipe

Every KayKit character is skinned to the same 23-bone rig (Rig_Medium), so parts from different characters mix on one skeleton and every animation plays on every mix. A recipe names one option per slot.

SlotOptions (source model)Driven by
Headrogue (Rogue)Fixed: one face for every profile
Headwearnone · helmet (Knight) · hat (Mage)Financial knowledge: low · medium · high
Outfitbarbarian · ranger · knight (body, arms, legs)Banking products: few · some · many
Backnone · quiver (Ranger) · cape (Knight)Banking products: few · some · many
LoopIdle_A · Walking_A · Running_ADigital affinity: low · medium · high

Slider tiers: 0 to 33 low, 34 to 66 medium, 67 to 100 high. The sliders snap to 0, 50 and 100, so each lands in the middle of a tier.

Profiles

The average of the three sliders picks the profile. The profile sets the title, the story, the UI preview and the legibility preset; the parts follow each slider on its own, so mixed answers give mixed figures.

AverageProfilePersonaLegibility preset
below 34NewbieBeatLarge
34 to 66All-rounderLenaRegular
67 and upPower userMaxSmall

Colour

The figure follows the app, not the asset. All colour is computed in OKLCH from the live tokens and updates whenever the theme or a custom colour theme changes.

Monochrome body

Each texture pixel keeps its lightness and takes the theme hue: from whichever of --color-fg and --color-bg carries more chroma (fallback hue 264, brand blue), at the ds4 neutral tint of 0.25. Lightness is squeezed into L 0.32 to 0.97 on Light and L 0.24 to 0.86 on Dark, so the figure never matches the background.

One accent

Colour is spent in one place. The dyeable cloth swatches, the helmet's metal and, bare-headed only, the newbie's hair take the hue of --color-fg-interactive on the ds4 ramp law C = 0.22 × (1 − L), anchored at step 700 on Light and 600 on Dark. In Monochrome themes that is the theme hue; in Multi-color themes it is the primary accent. Under a helmet or hat the hair stays neutral, so headwear and hair never merge.

Light and shadow

LightDark
StageTransparent canvas; the floor only catches the shadow
Shadow--color-overlay-tint at 20 %black at 55 %
Spotlight poolnone--color-overlay-tint at 25 %, the Dark content-indication strength, so the shadow stays visible
Key · fill · rim2.2 · 1.15 · 01.8 · 0.85 · 2.2

The key light comes from the right, so the shadow falls back left onto the page rather than out of the viewport.

Staging

WhereSizeBehaviour
Profile > User Type1.5×Editable through the sliders; drag to turn
Overview, Payments, Account details, Custody account, Position details1×Decoration: reads the saved recipe, no interaction
Below 62remProfile: beside the UI preview, in the flow. Other screens: hidden, no room next to dense content

On desktop the stage is fixed to the lower right corner. The figure keeps 64dp to the right and bottom edges, measured on one fixed capsule (2.65 m tall, 0.8 m radius), so it stands on the same spot whatever it wears. The stage sits behind the content but in front of the page background: .main-content gets isolation: isolate on these screens and the stage takes z-index: -1. The canvas is click-through; the figure is hit-tested against an invisible capsule.

Motion

MomentSpec
Part swapSquash out 168 ms, ease-in (0.4, 0, 1, 1) to scale 1.06 / 0.92, swap the parts, spring back 420 ms, ease-out (0.22, 1, 0.36, 1). During a drag only the latest recipe waits.
Loop changeCross-fade 280 ms between Idle, Walk and Run
Rest poseTurned 30° toward the viewer's left, heading for the bottom centre of the screen
ScrollAbout 7° per 100 px, tied to the scroll position and eased
DragTurns with the pointer, then coasts out (damping 0.92 per frame)
Reduced motionNo loops, tweens, coasting or scroll turn: a still pose; swaps happen instantly

The canvas renders only while it is on screen and the tab is visible.

Add the character to a screen

  1. Load the two scripts at the end of the page:
    <script src="js/profile-persona.js"></script>
    <script type="module" src="js/profile-persona-character.js"></script>
  2. Add the page's data-screen to AMBIENT_SCREENS in js/profile-persona-character.js.
  3. Add .body[data-screen="…"] .main-content to the isolation: isolate rule in css/styles.css. Without it the figure renders behind the page background and stays invisible.

Assets

assets/3d/kaykit/: knight, mage, rogue, barbarian, ranger (.glb, parts on Rig_Medium) plus rig-medium-general.glb and rig-medium-movement.glb (animation clips). KayKit Adventurers 2.0 by Kay Lousberg, CC0. Runtime: three.js 0.170 from jsDelivr.