Skip to content

Enhancement: Profile Customization (Mask)#456

Open
baltinerdist wants to merge 40 commits intoamtgard:masterfrom
baltinerdist:feature/player-profile-enhancements
Open

Enhancement: Profile Customization (Mask)#456
baltinerdist wants to merge 40 commits intoamtgard:masterfrom
baltinerdist:feature/player-profile-enhancements

Conversation

@baltinerdist
Copy link
Copy Markdown
Contributor

@baltinerdist baltinerdist commented Apr 10, 2026

Overview

This PR adds a comprehensive Design My Profile customization system to the Playernew player profile, giving players meaningful control over the presentation of their persona — appearance, identity, and story — all within the existing profile page.


Features

Welcome Tab

  • New first/default tab in the Design My Profile modal — a friendly, plain-language tour for first-time customizers.
  • Hero intro panel plus 5 feature cards (one per other tab) with colored icons, mini visual mockups, and click-to-jump CTAs that switch directly to the corresponding panel.
  • Quick tips callout explaining that nothing saves until Save is clicked.

About Tab

  • About Persona — A Markdown field for a short in-character persona description (rendered via marked.js + DOMPurify).
  • My Story — A longer Markdown field for backstory, lore, or personal history.
  • Both fields support live preview (Edit / Preview toggle) inside the modal before saving.

Beltline Widget

  • Displays a player's peerage relationships on their About tab: My Peers (who gave them peerage awards) and My Associates (who they have given peerage to).
  • Show My Beltline privacy toggle — players can hide this widget from their public profile.

My Milestones Timeline

  • Auto-generated chronological timeline of significant events: awards earned, titles received, masteries, paragons, knight elevation, officer roles, and custom milestones.
  • Players can toggle which milestone types appear, enable compact mode, and add fully custom milestones (date, icon picker, description).
  • Milestone labels are deduplicated — "Order of the Flame" → "Master Flame"; peerage belt titles don't duplicate as separate milestone entries.

Colors Tab

  • Hero background color with 8 solid presets and a custom color picker.
  • Accent color applied to stat cards, tab indicators, and interactive elements — with 8 matching presets.
  • Gradient hero — optional two-color gradient using a secondary color picker, with 8 gradient presets.
  • Heraldry overlay strength — Low / Medium / High opacity for the background heraldry pattern.
  • Live color preview panel shows how the hero header will look before saving.

Name Tab (Name Builder)

  • Prefix selector — dropdown populated from the player's earned titles and awards (noble ranks, masteries, paragons), plus a free-text "Other…" option.
  • Core Name — editable persona name field.
  • Suffix selector — same title list, usable as a suffix instead (e.g. "the Overpowered", "Esquire").
  • Comma toggle — adds a comma before the suffix (e.g. "Aria, the Bold").
  • Pronunciation Guide — optional phonetic guide displayed in parentheses under the hero name.
  • Name Font — 10 Google Fonts selectable via live preview cards (each card shows the player's actual name in that font):
    • Cinzel, Cinzel Decorative, IM Fell English, UnifrakturMaguntia, Metamorphous, Uncial Antiqua, Pirata One, Almendra, Pinyon Script, Great Vibes
  • Persona Display Controls — per-player toggles to show/hide mundane first name, mundane last name, and email address from other logged-in users (monarchy/admins always see them).

Photo Focus Tab

  • Canvas-based focus tool with a draggable/resizable circle overlay for setting the avatar thumbnail crop point.
  • Players drag the circle to their face/subject and resize it to control zoom level.
  • Saved focus point is applied client-side on every page load using object-fit: cover + object-position (handles EXIF-rotated mobile photos without distortion).

Notes Tab

  • Officers and the player themselves can leave internal notes on a profile.
  • Player can close out their own notes (self-service clear with confirmation modal).
  • Notes visibility is role-restricted.

DB Migrations

File Change
2026-04-04-player-profile-customization.sql 9 new columns: about_persona, about_story, color_primary, color_accent, name_prefix, name_suffix, photo_focus_x/y/size
2026-04-04-show-beltline.sql show_beltline column
migration_name_font.sql name_font column
(inline) color_secondary, hero_overlay, suffix_comma, pronunciation_guide, show_mundane_first/last, show_email, milestone_config

Test Plan

  • Open Design My Profile; verify the Welcome tab is the first/default tab and that each card jumps to the correct panel
  • Open Design My Profile on your own profile; verify all 6 tabs render and save correctly
  • Write About Persona and My Story in Markdown; verify rendered output on About tab
  • Verify beltline widget shows correct peers/associates; verify hiding it with the toggle
  • Add, edit, and delete custom milestones; verify timeline ordering
  • Toggle milestone type visibility and compact mode
  • Apply a color preset and custom colors; verify hero, accent, and gradient render correctly
  • Build a name with prefix + core + suffix; test comma toggle and pronunciation guide
  • Select each of the 10 name fonts; verify the preview card renders in that font and the hero name updates on save
  • Upload a portrait photo taken with a phone (EXIF rotation); verify avatar is not distorted
  • Use the Photo Focus tool; drag/resize the circle; verify avatar crops to that focal point after save
  • Verify privacy toggles (mundane name/email visibility) work for non-admin visitors

🤖 Generated with Claude Code

@baltinerdist baltinerdist force-pushed the feature/player-profile-enhancements branch from 4b9098d to 7350d14 Compare April 15, 2026 00:02
Avery Krouse and others added 29 commits April 15, 2026 11:51
…me Builder, Beltline

Add comprehensive player profile customization via "Design My Profile" modal:
- About section with markdown (About Persona + My Story) rendered via marked.js + DOMPurify
- Custom color scheme (primary hero bg + accent) with 8 presets and custom picker
- Persona Name Builder (prefix + core name + suffix from earned titles/awards)
- Photo focus tool with circle overlay for avatar thumbnail positioning
- Precise JS-based avatar focus rendering (pixel-perfect zoom/pan)
- Increased photo/heraldry upload limit to 1MB
- Beltline widget on About tab showing peerage relationships (My Peers + My Associates)
- Show My Beltline toggle for privacy control
- DB migration: 10 new columns on ork_mundane

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Pronunciation guide field on Name tab, displayed in parentheses under
  persona name in the hero section
- Persona Display Controls: Show Mundane First Name, Show Mundane Last Name,
  Show Email Address toggles with tooltip explanations
- Monarchy/admins always see real name and email regardless of toggles
- Other logged-in users see based on player preference (default: visible)
- Sidebar Player Details now respects visibility toggles
- Hero real name display respects visibility toggles
- DB migration: 4 new columns (pronunciation_guide, show_mundane_first,
  show_mundane_last, show_email)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pronunciation guide, real name, and pronouns now display on one line
separated by bullets (•) instead of stacked vertically. Bullets only
appear between items that are present, so a profile with only pronouns
shows just pronouns with no stray separators.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Hero background can now be a two-color gradient (135deg) via secondary
  color picker with "Enable gradient" toggle on Colors tab
- Heraldry overlay strength selector (Low/Medium/High) controls how much
  the heraldry image shows through the hero background
  - Low: 6% opacity, Medium: 12% (default), High: 22% opacity
- Live preview in Design My Profile updates as settings change
- Reset button clears gradient and restores medium overlay
- DB migration: color_secondary, hero_overlay columns

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…dropdown

- Add a.is_title = 1 to title query to capture noble titles (Baronet,
  Count, Duke, etc.) which were previously excluded
- If player has any Master X awards (Master Rose, Warlord, etc.), add
  standalone "Master" entry to prefix/suffix dropdown
- If player has any Paragon X awards, add standalone "Paragon" entry
- Standalone entries are prepended so they appear at top of dropdown

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Single-click toggle button next to the Suffix label adds or removes a
comma between the core persona name and suffix, e.g.:
  "Duchess Iona Hallewell Thingsdoer, Ambassador" vs without comma.
Toggle state persists in DB (suffix_comma column) and updates the live
preview, hero display, and Design modal preview.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…lone button

Comma toggle is now a small ',' button positioned between the Core Name
and Suffix fields instead of inside the Suffix label. Prefix and Suffix
fields are wider (flex:1.2), Core Name is narrower (flex:1) to give
more room to the dropdown fields.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Modal width 640px → 720px. Core name flex ratio increased to 1.8
(from 1) while prefix/suffix reduced to 1 (from 1.2), giving the
persona name field the majority of the row width.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
8 gradient preset swatches: Midnight Royal, Forest Ocean, Ember, Mystic,
Deep Forest, Charcoal, Ocean Teal, Autumn. Clicking a gradient preset
sets primary, accent, and secondary colors and enables the gradient
toggle automatically. Preset highlight syncs correctly for both solid
and gradient swatches.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
CDN scripts were at the bottom of the template, but the markdown
rendering IIFE ran earlier — so marked/DOMPurify were undefined and
the fallback plain-text escaper was used instead. Move the CDN script
tags to before revised.js so they're available when renderMd() runs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds a vertical alternating timeline beneath My Peer/My Associate sections.
9 auto-detected milestone types (first sign-in, level 6 per class, master,
paragon, knight, title, became associate, took associate, officer) plus
custom user-defined milestones with a visual icon picker.

Configurable via new Milestones tab in Design My Profile modal — each type
can be toggled on/off. Custom milestones (add/delete) stored in new
ork_player_milestones table; config stored in ork_mundane.milestone_config.

Fixes: milestone AJAX in correct player() method, deduplication of awards
that match multiple types, alternating layout CSS double-swap bug, date
color uses profile accent color.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…self-service close-out

- Hide the Notes tab from public view; only the profile owner (logged in) sees it,
  and only when they have notes. Admins always see it.
- Add a blue infobox explaining the tab contains historically imported data and
  instructing users to reconcile with their Monarch or PM before closing out.
- "Click here" link opens a confirm modal; on confirm, POSTs to
  PlayerAjax/player/{id}/clearnotes which deletes all notes and removes the tab.
- New ClearNotes() method in class.Player.php (authorized for own profile or park admin).
- Dark mode support for the infobox.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add custom name font picker to Design My Profile (Name tab): 10 Google
  Fonts (medieval, gothic, script styles) rendered as live preview cards;
  selected font applied to hero header name on save
- Add name_font column to ork_mundane; thread NameFont through class.Player,
  controller.PlayerAjax, and Playernew_index template
- Fix profile photo distortion caused by applyFocus using naturalWidth/Height
  with objectFit:initial — EXIF-rotated phone photos were being squished;
  replaced with object-fit:cover + object-position approach
- Fix Notes tab clear-modal event handlers (chained .on() → $(document).on())
- Improve milestone dedup: strip "Order of the/of" prefix on master labels;
  filter title milestones that duplicate peerage terms or master milestones

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
New first-tab introduction explains each customization area in plain
language, with feature cards that jump directly to the corresponding
panel and inline mockups previewing what each feature looks like.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds an eyeball button to the global topnav (only on Player/profile/*
routes) that swaps between the live profile (A) and an experimental
"hardcore" redesign (B) via ?design=b. The B variant lives in its own
template Playernew_index_b.tpl with all overrides scoped under
body.pn-variant-b — Cinzel display type, larger hero with key-facts
cluster, glassy badges, refined stat cards, sidebar accent stripes,
filled timeline nodes, polished tab pills, modal width bump, and a
page-load stagger. Removal: delete the if-block in Player::profile,
the eyeball block in default.theme, and Playernew_index_b.tpl.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds an A/B toggle (eyeball icon in topnav, only on Player/profile/*)
that swaps the live profile to a maximum-cringe Geocities homepage
tribute via ?design=b. The B variant lives in Playernew_index_b.tpl
with all overrides scoped under body.pn-variant-b: tiled starfield
background, Comic Sans + Times + Press Start 2P + Bungee Shade type,
WordArt rainbow persona name, scrolling marquee, "Under Construction"
GIF facsimiles, blinking visitor counter, glitter dividers, sign-my-
guestbook button, MIDI music indicator, web ring, "Best viewed in
Netscape 4.0 at 800x600" badge, and an aol.com email footer. The
toggle eyeball blinks magenta with a hue-rotate animation when the
B variant is active.

Removal: delete the if-block in Player::profile, the eyeball block in
default.theme, and Playernew_index_b.tpl.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The eyeball icon now cycles A → B (Geocities) → C (MS-DOS) → A.
Variant C transforms the player profile into a CGA/EGA monochrome
DOS application: phosphor-green VT323 type on black, CRT scanlines
and vignette, BIOS header bar, blinking C:\\ORK> command prompt,
ASCII castle art in the hero, [bracket] badges, sidebar cards
wrapped in ╣ ╠ box-drawing chars, PLAYER.SYS LOADED progress bars
made of █ and ░ blocks, F-key shortcut bar, sticky bottom status
bar with NUM/CAPS/SCRL indicators, and a phosphor-block cursor
follower replacing the system pointer.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The eyeball icon now cycles A → B (Geocities) → C (MS-DOS) → D (D&D) → A.
Variant D restyles the player profile as a 5e-style character sheet:
parchment background with deep red, gold trim, and ink shadows; Uncial
Antiqua persona name with Cinzel section headers; the four stat cards
become six ability-score boxes (STR/DEX/CON/INT/WIS/CHA) with values
derived from real attendance/awards/titles plus floating modifier
roundels; a vitals strip injects HP/AC/Initiative/Proficiency boxes;
a character info bar shows Class & Level / Race / Background /
Alignment computed from real data; the sidebar cards become bordered
parchment manuscripts with ❦ fleurons; tabs become Player's Handbook
chapter dividers; tab content gets drop-cap first letters; and a
flavor quote announces the player's chronicles.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Backs out the Geocities, MS-DOS, and D&D character sheet variants
along with the eyeball cycler in default.theme. Returns the player
profile and topnav to the state at e72e0e1 (Welcome tab).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds an A/B toggle (a small gold quill icon in the topnav, only on
Player/profile/* routes) that swaps the live profile with a quietly
medieval refinement via ?design=b. Variant B preserves the layout,
palette, and spacing of A; the only changes are:

  1. Persona name in Cinzel (same size, color, position)
  2. Stat numbers in Cinzel with tabular figures
  3. Sidebar card headers: flat border replaced with a fleuron rule
     (thin gold line + small wave + dot, drawn in inline SVG)
  4. Tab content section headers and timeline heading: same fleuron
  5. Drop cap on the first paragraph of the About section
  6. Stat cards / sidebar / tabs warm to a faint gold on hover
  7. Hairline gold corner ticks on the hero (4 SVG L-marks)
  8. Active tab gets a thin double-rule + soft gold inner glow

Removal: delete the if-block in Player::profile, the eyeball block
in default.theme, and Playernew_index_b.tpl.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Design for a new Custom Title award option that allows giving named titles
aliased to core non-officer titles (e.g., Brother-in-Battle → Page).
Aliased entries receive full substitution semantics in Titles tab,
My Associates, and Beltline Explorer, with display-name override.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…iliation

Adds the full task breakdown (migration, helper, save/update, query
substitution, UI modal, chip rendering, edit-modal reconciliation, end-to-end
verification). Spec updated with the edit-modal reconciliation flow.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Migration adds ork_awards.alias_award_id (nullable FK to ork_award) and
inserts a sentinel ork_award row named 'Custom Title' (is_title=1,
peerage='None'). These power the Custom Title feature: aliased rows get
full peerage/title substitution at query time via COALESCE.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds getCustomTitleAwardId() instance helper (cached) and extends
add_player_award() to persist AliasAwardId on the new ork_awards.alias_award_id
column. Validates that alias targets exist, are non-officer, are a title or
peerage entry, and are not the Custom Title sentinel itself.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…fication

UpdateAward now handles optional CustomName, AwardId (constrained to the
Custom Award/Title sentinels), and AliasAwardId. Validates alias targets
like AddAward. get_award() includes alias_award_id in its audit payload.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
BeltlineData (Relationships, Knights, AllKnightIds) now LEFT JOINs
ork_award via ma.alias_award_id and uses COALESCE(alias.peerage, a.peerage)
as the effective peerage. Display name prefers ma.custom_name so aliased
Custom Titles show their custom name in beltline relationships.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All four peerage-filtered queries (BeltlinePeers, BeltlineAssociates,
MyAssociates, Titles) gain LEFT JOIN ork_award alias and use
COALESCE(alias.peerage, a.peerage) as the effective peerage. Display names
prefer ma.custom_name so aliased Custom Titles show their chosen name.
addaward/updateaward cases pipe CustomName and AliasAwardId through to the
model.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Avery Krouse and others added 11 commits April 15, 2026 11:52
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Seed migration: per-kingdom Custom Title kingdomaward rows (is_title=1)
- AwardsForPlayer: LEFT JOIN alias, return effective peerage/is_title/officer_role/title_class and AliasAwardId/AliasAwardName/AliasPeerage per row
- model.Award: Custom Title joins the custom option bucket with data-custom-title and data-award-id attrs (Custom Award gets matching data-custom-award attr)
- controller.Player::profile: resolves Custom Title sentinel, builds CustomTitleAliasOptions (Peerage ladder + Titles) for the modal dropdown

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Playernew_index.tpl: alias dropdown markup (peerage ladder + other titles optgroups)
- revised.js: select-change handler detects Custom Title via data-custom-title, toggles alias row, relabels custom-name field, resets state on open/clear, adds AliasAwardId to the save FormData
- controller.Admin: addaward/updateaward pipe CustomName + AliasAwardId through to the model

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Awards table and Titles tab rows now show "aka <alias name>" muted below
the custom name whenever AliasAwardId is set. Edit-action JSON payload
gains AwardId/CustomName/AliasAwardId/AliasAwardName so the edit modal can
preselect the alias and radio state. Adds .pn-award-alias-sub CSS.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…tles

The edit-award modal now shows a Custom Award ↔ Custom Title radio toggle
and an alias dropdown for any award whose AwardId matches the Custom Award
(94) or Custom Title sentinel. Switching type updates the label, toggles
alias visibility, and writes AwardId/AwardName/AliasAwardId into the
update POST. PnConfig exposes customAwardId and customTitleAwardId.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The original T11 commit only updated the edit-button JSON payload; the
actual aka-subtitle markup was lost during the multi-step Python patch.
This adds the span.pn-award-alias-sub rendering inside both the Awards
table and Titles tab cells, and widens the CSS selector to allow the
subtitle to wrap inside a nowrap column.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…rd_id

UpdateAward was only updating ork_awards.award_id when reclassifying between
Custom Award and Custom Title sentinels. But AwardsForPlayer resolves the
base award via kingdomaward_id → ka.award_id → a.*, so the is_title flag
stayed 0 and the reconciled row never moved into the Titles tab.

Now, when the AwardId flips between 94 and the Custom Title sentinel, the
update also looks up the matching 'Custom Award' / 'Custom Title' kingdomaward
row in the same kingdom and rewrites ork_awards.kingdomaward_id to match.
The effective is_title, peerage, and officer_role then resolve correctly
through the existing query layers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When a player selects Other... for their name prefix or suffix in the
Design My Profile name builder, a yellow info banner appears reminding
them to only use name elements they're entitled to claim. Shown on page
load when the currently-saved value is a free-text custom, and toggles
live with the select dropdown.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Yellow info banner reminds players that their About section is public and
warns that kingdom/park officers can take action on impermissible content.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…rning

Both About-tab and name-builder entitlement banners now use the yellow
fa-exclamation-triangle icon. Name-builder wording changed from "earned"
to "been granted" to better reflect the permissions model.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Yellow yield-triangle banner in the Milestones tab reminds players to
keep custom milestones accurate, particularly for awards, titles, and
other recognitions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@baltinerdist baltinerdist force-pushed the feature/player-profile-enhancements branch from dbcc59a to 7e56ef7 Compare April 15, 2026 15:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant