diff --git a/client/src/ui/NpcInfoPanel.ts b/client/src/ui/NpcInfoPanel.ts index 7bd0817..0464777 100644 --- a/client/src/ui/NpcInfoPanel.ts +++ b/client/src/ui/NpcInfoPanel.ts @@ -35,6 +35,7 @@ export class NpcInfoPanel { private separatorEl: HTMLDivElement; private needsBarsContainer: HTMLDivElement; private needsBars: Map = new Map(); + private backstoryEl: HTMLDivElement; private statsContainer: HTMLDivElement; private statElements: Map = new Map(); private statusTab!: HTMLDivElement; @@ -53,12 +54,12 @@ export class NpcInfoPanel { position: fixed; top: 16px; right: 16px; - width: 280px; + width: 400px; border-radius: 16px; border: 3px solid ${EB.borderOuter}; background: ${EB.borderGap}; z-index: 1000; - transform: translateX(350px); + transform: translateX(470px); transition: transform 0.35s cubic-bezier(0.22, 1, 0.36, 1); box-shadow: 0 0 20px rgba(80, 60, 160, 0.4), @@ -154,7 +155,7 @@ export class NpcInfoPanel { flex: 1; text-align: center; padding: 8px 0; - font-size: 9px; + font-size: 18px; cursor: pointer; color: ${EB.textPrimary}; border-bottom: 2px solid ${EB.borderOuter}; @@ -167,7 +168,7 @@ export class NpcInfoPanel { flex: 1; text-align: center; padding: 8px 0; - font-size: 9px; + font-size: 18px; cursor: pointer; color: ${EB.textMuted}; user-select: none; @@ -197,7 +198,7 @@ export class NpcInfoPanel { // Name this.nameEl = document.createElement('div'); this.nameEl.style.cssText = ` - font-size: 13px; + font-size: 26px; color: ${EB.textPrimary}; text-align: center; padding: 2px 0 4px; @@ -209,18 +210,34 @@ export class NpcInfoPanel { // Activity this.activityEl = document.createElement('div'); this.activityEl.style.cssText = ` - font-size: 10px; + font-size: 20px; color: ${EB.textSecondary}; text-align: center; padding-bottom: 2px; `; this.statusContent.appendChild(this.activityEl); + // Backstory text + this.backstoryEl = document.createElement('div'); + this.backstoryEl.style.cssText = ` + font-size: 14px; + color: ${EB.textSecondary}; + text-align: center; + padding: 2px 8px 4px; + font-family: 'Press Start 2P', monospace; + line-height: 1.6; + font-style: italic; + min-height: 0; + transition: min-height 0.3s ease, opacity 0.3s ease; + opacity: 0; + `; + this.statusContent.appendChild(this.backstoryEl); + // Decorative separator (EarthBound diamond pattern) this.separatorEl = document.createElement('div'); this.separatorEl.style.cssText = ` text-align: center; - font-size: 7px; + font-size: 14px; color: ${EB.textMuted}; padding: 4px 0; letter-spacing: 6px; @@ -242,7 +259,7 @@ export class NpcInfoPanel { const statsSeparator = document.createElement('div'); statsSeparator.style.cssText = ` text-align: center; - font-size: 7px; + font-size: 14px; color: ${EB.textMuted}; padding: 4px 0; letter-spacing: 6px; @@ -287,7 +304,7 @@ export class NpcInfoPanel { hide(): void { this.visible = false; - this.outerFrame.style.transform = 'translateX(350px)'; + this.outerFrame.style.transform = 'translateX(470px)'; } updateInfo(entity: EntityState): void { @@ -301,6 +318,18 @@ export class NpcInfoPanel { this.activityEl.textContent = goal ? (ACTIVITY_LABELS[goal] ?? goal) : 'Idle'; } + // Update backstory + const backstory = entity.backstory; + if (backstory && backstory.length > 0) { + this.backstoryEl.textContent = `"${backstory}"`; + this.backstoryEl.style.opacity = '1'; + this.backstoryEl.style.minHeight = '40px'; + } else { + this.backstoryEl.textContent = ''; + this.backstoryEl.style.opacity = '0'; + this.backstoryEl.style.minHeight = '0'; + } + if (entity.needs) { this.updateNeeds(entity.needs); } @@ -346,7 +375,7 @@ export class NpcInfoPanel { const labelEl = document.createElement('div'); labelEl.style.cssText = ` - font-size: 9px; + font-size: 18px; color: ${EB.textSecondary}; text-transform: uppercase; letter-spacing: 1px; @@ -355,7 +384,7 @@ export class NpcInfoPanel { const valueEl = document.createElement('div'); valueEl.style.cssText = ` - font-size: 10px; + font-size: 20px; color: ${EB.textPrimary}; text-shadow: 1px 1px 0 rgba(0,0,0,0.5); `; @@ -437,7 +466,7 @@ export class NpcInfoPanel { el.style.cssText = ` display: flex; justify-content: space-between; - font-size: 9px; + font-size: 18px; `; const labelEl = document.createElement('span'); labelEl.style.cssText = `color: ${EB.textSecondary}; text-transform: uppercase; letter-spacing: 0.5px;`; @@ -477,7 +506,7 @@ export class NpcInfoPanel { if (relationships.length === 0) { this.relationshipsContent.innerHTML = ''; const empty = document.createElement('div'); - empty.style.cssText = `text-align: center; color: ${EB.textMuted}; font-size: 9px; padding: 16px 0;`; + empty.style.cssText = `text-align: center; color: ${EB.textMuted}; font-size: 18px; padding: 16px 0;`; empty.textContent = 'No relationships yet'; this.relationshipsContent.appendChild(empty); return; @@ -520,7 +549,7 @@ export class NpcInfoPanel { const tierLabel = document.createElement('div'); const icon = tierIcons[tier] ?? ''; - tierLabel.style.cssText = `font-size: 8px; color: ${EB.textSecondary}; margin-bottom: 4px;`; + tierLabel.style.cssText = `font-size: 16px; color: ${EB.textSecondary}; margin-bottom: 4px;`; tierLabel.textContent = `${icon} ${tier}`; tierEl.appendChild(tierLabel); @@ -539,7 +568,7 @@ export class NpcInfoPanel { const toggle = document.createElement('div'); toggle.style.cssText = ` - font-size: 7px; + font-size: 14px; color: ${EB.borderOuter}; cursor: pointer; user-select: none; @@ -571,7 +600,7 @@ export class NpcInfoPanel { const memEl = document.createElement('div'); memEl.style.cssText = 'margin-bottom: 8px;'; const memLabel = document.createElement('div'); - memLabel.style.cssText = `font-size: 8px; color: ${EB.textMuted}; margin-bottom: 4px;`; + memLabel.style.cssText = `font-size: 16px; color: ${EB.textMuted}; margin-bottom: 4px;`; memLabel.textContent = '\u25CB Memories'; memEl.appendChild(memLabel); @@ -594,7 +623,7 @@ export class NpcInfoPanel { const toggle = document.createElement('div'); toggle.style.cssText = ` - font-size: 7px; + font-size: 14px; color: ${EB.borderOuter}; cursor: pointer; user-select: none; @@ -630,11 +659,11 @@ export class NpcInfoPanel { align-items: center; gap: 4px; margin-bottom: 3px; - font-size: 8px; + font-size: 16px; `; const nameEl = document.createElement('span'); - nameEl.style.cssText = `color: ${EB.textPrimary}; min-width: 70px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;`; + nameEl.style.cssText = `color: ${EB.textPrimary}; min-width: 100px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;`; const bondIcon = bond === 'partner' ? ' \u{1F48D}' : bond === 'former_partner' ? ' \u{1F48D}\u{FE0E}' : ''; nameEl.textContent = name + bondIcon;