- Replace clamp(Xvw, Yvw, Zvw) with clamp(Xrem, Yvw, Zrem)
- Prevents font sizes from scaling excessively on ultrawide monitors
- Now minimum and maximum values are fixed units while middle value remains responsive
- Fixes info box, stats, calendar, weather, and all other text elements
- Replace all vw-based font-size properties with clamp() to prevent excessively large text
- Set maximum font sizes to prevent issues on 3440x1440 and other ultrawide displays
- Maintain responsive behavior for normal and mobile screen sizes
- Fix gap properties using vw for better spacing consistency
- Add pre-encounter narrative configuration modal with combat/summary style settings
- Change POV fields to text inputs (default: narrator) for custom character names
- Fix targeting system for enemies with spaces in names (e.g., 'Gilded Thrall 1')
- Display character-specific sprites/avatars in targeting modal instead of generic emojis
- Add combat difficulty scaling guidance to prevent trivial god defeats or endless wolf battles
- Integrate tracker updates in combat summary generation (together mode)
- Update auto-save logs description to clarify file storage vs chat history
- Apply extension theming to Close Combat Window button
- Fix checkpoint button display with expandMessageActions setting
- Add body class observer to update buttons when setting toggles
- Add cleanupCheckpointUI function for extension disable
- Separate Quests from Inventory with independent toggle
- Add horizontal scrolling to Info Box dashboard
- Add divider between Inventory and Quests sections
- Add removeCharacter() function to delete characters from panel and saved data
- Remove character from both lastGeneratedData and committedTrackerData
- Add X button to character card header with hover effects
- Button removes character from display and prevents re-inclusion in next generation
- Updates are persisted to chat metadata
- Add npcAvatars storage to extension settings for custom NPC images
- Implement getCharacterAvatar() to check custom avatars first
- Add uploadNpcAvatar() function with file validation (2MB max, images only)
- Make character avatars clickable with visual feedback
- Support left-click to upload and right-click to remove custom avatars
- Add camera icon overlay on hover with smooth animations
- Store avatars as base64 data URIs for persistence across sessions
- Add .rpg-attr-name styling to match .rpg-stat-name
- Use SmartTheme colors instead of default white background
- Add focus state with highlight border
- Include .rpg-attr-toggle and .rpg-attr-remove in selectors
Fixes white background on RPG attribute text inputs (STR, DEX, etc.)
in the Tracker Editor modal.
- Fix stripBrackets() removing Skills section header
- Add structural header whitelist (Skills, Status, Inventory, etc.)
- Implement smart look-ahead to detect content below labels
- Previous logic incorrectly removed 'Skills:' when followed by category labels
- Add proper theming to category action buttons (.rpg-category-action)
- Match styling of view toggle buttons
- Use SmartTheme colors for better visibility
- Fix RPG attributes styling in Tracker Editor
- Change background from --rpg-accent to --SmartThemeBlurTintColor
- Update border to match other themed inputs
Resolves issue where skills with categories were all showing as 'Uncategorized'
due to the Skills section being truncated during parsing.
Show helpful message when Recent Events tracking is disabled in tracker config.
Changes:
- Check if recentEvents is enabled in trackerConfig before rendering
- If disabled, show dimmed widget with overlay message:
- Info icon + explanation text
- "Enable in Tracker Settings" button
- Button opens Tracker Settings and switches to Info Box tab
UX Improvements:
- Widget opacity reduced to 0.6 to indicate disabled state
- Message centered with clear visual hierarchy
- Button has hover/active states with elevation feedback
- Clicking button directly navigates to the right settings location
Technical Implementation:
- attachDisabledStateHandlers() opens Tracker Settings modal
- Auto-switches to Info Box tab after 100ms delay
- Graceful fallback if button not found (console warning)
CSS Additions:
- .rpg-widget-disabled: Dimmed overlay state
- .rpg-widget-disabled-message: Centered message container
- .rpg-widget-enable-btn: Styled action button with hover effects
Benefits:
- Users immediately understand why Recent Events isn't updating
- One-click access to fix the issue
- Clear visual feedback about widget state
- Pattern can be reused for other widgets (Skills, etc.)
Next Steps:
- Apply this pattern to other widgets that depend on tracker config
- Consider adding similar disabled states for Skills, Stats, etc.
Related: Recent Events widget implementation, tracker config system
Add comprehensive Skills widget to dashboard system with category organization,
XP tracking, level progression, and multiple view modes.
Widget Features:
- Three sub-tabs: All Skills, By Category, Quick View
- Level-up and level-down buttons for manual progression
- XP progress bars with visual feedback
- Search and filter functionality
- Category collapse/expand in By Category view
- Editable skill names and categories
- Delete skills and categories
- Add new skills and categories
- Configurable max level and XP display
UI Improvements:
- Scrollable content area for large skill lists
- Responsive card layout
- Shortened tab labels for compact display ("All", "Quick" vs "All Skills", "Quick View")
- Proper flex layout for skill names (no longer truncated)
- Level badges and action buttons
Technical Implementation:
- Event handler deduplication to prevent exponential level-up bug
- Flag-based handler attachment: container.dataset.handlersAttached
- Nested flex containers for proper space distribution
- Scrollable views wrapper matching Inventory/Quests pattern
Dashboard Integration:
- Added Skills tab to defaultLayout.js (tab 5)
- Icon: fa-solid fa-book (fixed invalid fa-book-sparkles)
- Dimensions: 3x7 grid cells
- Default config: All Skills tab, show XP, show categories
- Auto-arrange support in dashboardManager.js
- Skills category group with priority order 6
- Auto-creates Skills tab when skills widgets detected
- Widget registration in dashboardIntegration.js
Widget Files:
- src/systems/dashboard/widgets/userSkillsWidget.js (new)
- Full widget implementation with all sub-tabs and features
- State management with Map-based storage
- Category-based and flat views
- Search/filter/sort functionality
Styling:
- style.css: Added skills widget styles
- Skill cards, headers, action buttons
- Level-down button with accent color
- XP progress bars
- Category sections
Fixes from iteration:
1. Invalid FontAwesome icon (fa-book-sparkles → fa-book)
2. Tab labels too wide (shortened to single words)
3. Skill names truncated (fixed with proper flex structure)
4. Widget height incorrect (adjusted to h:7)
5. Level-up exponential bug (duplicate handlers, added flag guard)
6. No level-down button (added with minimum level 1)
7. No scrollbar on long lists (added .rpg-skills-views wrapper)
Category: skills
Integration: Fully integrated with dashboard v2.0 system
Tested: Layout, interactions, scrolling, level progression
Refs: AI tracker integration (separate commit)
Resolves overlap issue between long character names and level indicator
in 1x2 userInfo widgets. Level now displays at top-right corner flush
with container, while name remains at bottom with full width available.
- Changed level container position from bottom: 0 to top: 0
- Prevents text overlap for names like 'Seol Yi-hwan Lvl 1'
- Maintains clean, compact layout at 1080p and other resolutions
**Status Tab Layout Changes:**
- User Info widget: 1x2 vertical (left column) instead of 2x1 horizontal
- User Stats widget: scales from 1x3 (narrow) to 2x3 (wide)
- User Mood widget: 1x1 positioned below User Info
- User Attributes widget: scales from 2x4 (narrow) to 3x4 (wide), full width
**Technical Changes:**
- Update widget definitions to use column-aware defaultSize() functions
- userInfoWidget: Returns 1x2 for desktop, 1x1 for mobile
- userStatsWidget: Returns 1x3 for 2 cols, 2x3 for 3+ cols
- userAttributesWidget: Returns 2x4 for 2 cols, 3x4 for 3+ cols
- Remove autoLayout from resetLayout() to preserve default positions
- Add resetWidgetSizesToDefault() to apply column-aware sizes
- Update CSS for 1x1 compact avatar (round) and 1x2 wide avatar layouts
**User Info Widget Improvements:**
- 1x2 layout: Horizontal split with name left, level right over avatar
- 1x1 layout: Round avatar with bottom nameplate (flush positioning)
- Transparent glass-style backgrounds for better avatar visibility
- Proper aspect-ratio for circular avatar in compact mode
**Result:**
- Widgets scale intelligently based on panel width (2-4 columns)
- Desktop users get larger, more spacious layouts
- Mobile/narrow screens get efficient vertical stacking
- Reset Layout respects custom positions while applying responsive sizes
- Window resize triggers autoLayout via ResizeObserver for reflow
- Increase character name, traits, and emoji sizes for better mobile readability
- Limit Recent Events section to 150px max height on mobile
- Make events widget scrollable to save screen space
- Reduce padding and gaps for more compact layout
Changed from avatar + text layout to avatar as background with text overlay.
Previous approach: Tried horizontal/vertical layouts which caused either
horizontal or vertical scrollbars at narrow widths (w:1 h:1).
New approach: Avatar fills entire widget as background-image, name + level
display as centered overlay with semi-transparent backdrop and blur effect
for readability. Uses background-size: contain to show full avatar without
cropping.
Benefits:
- No layout conflicts - works at any widget size
- No scrollbars (horizontal or vertical)
- Full avatar visible without cropping
- Visually interesting design
- Simpler code (no layout switching logic)
Changes:
- userInfoWidget.js: Avatar set as background-image with contain sizing
- userInfoWidget.js: Simplified onResize (removed layout switching)
- style.css: Container uses background-image with gradient overlay
- style.css: Text container has backdrop-filter blur + dark background
- style.css: Simplified compact mode (no portrait/layout-specific rules)
Fixed text clipping in date display by applying mobile's proven size reductions
to narrow desktop widgets (< 3 grid units wide).
Root Cause:
- At narrow widths (~296px, 2 columns), date text wraps: "3rd Day of the Ninth Month" + "Tuesday"
- Top 1/4 of first line was clipped (top of "3" and "D" cut off)
- Mobile displays work perfectly at even smaller widths
Solution - Mirror Mobile Sizing:
Mobile uses smaller dimensions that prevent clipping:
- Padding: 0.3125rem (vs 0.375rem desktop)
- Gap: 0.3125rem (vs 0.375rem desktop)
- Font size: 0.8125rem (vs 0.875rem desktop)
- Label font: 0.625rem (vs 0.6875rem desktop)
Changes:
1. style.css (lines 2782-2812):
- Added .rpg-scene-info-compact class with mobile-like sizing
- Reduces padding, gaps, and font sizes
- Applied when widget width < 3 grid units
2. sceneInfoWidget.js (lines 367-385):
- Added onResize handler
- Applies .rpg-scene-info-compact at newW < 3
- Removes class at newW >= 3
- Matches pattern used for inventory/quests compact modes
Result: Date text displays without clipping at narrow widths, exactly as mobile does.
Fixes: Text clipping in scene info date display at 2-column layout (~296px)
Properly centered icons by wrapping text in spans and forcing exact button
dimensions to override base min-width: fit-content style.
Root Cause:
- Base .rpg-inventory-add-btn has min-width: fit-content
- Even with span hidden, button width wasn't constrained
- Icon appeared off-center with extra space to the right
Solution:
1. HTML Structure (inventoryWidget.js, questsWidget.js):
- Wrapped text in <span class="rpg-btn-label">
- Pattern: <i class="fa-solid fa-plus"></i><span class="rpg-btn-label"> Add Item</span>
- Applied to: Add Item, Add Location, Add Asset, Add Quest buttons
2. CSS (style.css):
- Hide labels: .rpg-inventory-compact .rpg-btn-label { display: none; }
- Force square dimensions: width: 32px !important (overrides fit-content)
- Center icon: display: inline-flex; justify-content: center; align-items: center
- Remove padding: padding: 0 (icon uses full 32px space)
Result: Perfect 32×32px square buttons with centered icons in compact mode,
matching the pattern used for sub-tab buttons throughout the codebase.
Fixes: Icon skewed left in Add Item/Quest buttons at narrow widths
Problem: CSS variables --rpg-bg and --rpg-accent have 0.9 opacity,
making all modals and menus transparent even with gradient backgrounds.
Solution: Use solid RGB colors directly in gradients:
- rgba(22, 33, 62, 1) instead of var(--rpg-accent)
- rgba(26, 26, 46, 1) instead of var(--rpg-bg)
Changes:
- style.css: .rpg-modal-content uses solid gradient
- tabContextMenu.js: Context menu uses solid gradient
- Both maintain inset shadow for depth
- Mobile long-press support included
Now modals and context menus have opaque backgrounds matching
widget styling instead of see-through transparency.
The Recent Events widget was appearing as a narrow "little calendar thing"
instead of filling the full container width. The root cause was that
.rpg-events-widget container was missing `width: 100%`.
Changes:
- Add `width: 100%` to .rpg-events-widget (style.css:2517)
This makes the notebook container fill the full widget width
- Remove incorrect `width: 100%` from .rpg-notebook-line (was at line 2597)
This was a previous incorrect fix targeting child elements instead of parent
The parent .rpg-dashboard-widget has `align-items: center`, which causes
flex children without explicit width to shrink to content width. Adding
`width: 100%` to the widget container ensures it stretches to fill the
allocated grid cell.
Fixes: #sceneinfo-width
Related: commit aa50b24 (reverted incorrect fix)
Features:
- Made RPG attributes (STR/DEX/CON/INT/WIS/CHA) fully customizable
- Added enable/disable toggle for entire RPG Attributes section
- Users can add/remove/rename/toggle individual attributes
- Custom attribute names now appear in AI prompts for dice rolls
- Added proper CSS styling for attribute editor fields
Bug Fixes:
- Fixed character stat editing showing 0% on blur but saving correctly
- Character stats now create Stats line if missing from AI response
- Separated stat name from editable percentage value
- Added value sanitization (removes %, validates 0-100 range)
- Stats line now inserts before Thoughts line when created
Technical:
- Added buildAttributesString() helper in promptBuilder.js
- Updated generateTrackerInstructions and generateContextualSummary
- Restructured character stat HTML to prevent nested contenteditable
- Enhanced updateCharacterField to handle missing Stats lines
- Removed legacy default preset/regex import code
Fixed Recent Events widget content not stretching to fill the full widget width.
Content appeared narrow like a "little calendar thing" with wasted space on the right.
**Problem:**
- Vertical height was fixed (widget fills height correctly) ✓
- But content (event lines) didn't stretch horizontally ✗
- Event lines only as wide as their text content
- Unused space on right side of widget
- Notebook appeared narrow and compact
**Root Cause:**
`.rpg-notebook-line` (individual event line container) missing `width: 100%` property.
Without this, the flex container shrinks to fit content's natural width instead of
expanding to fill the parent container (`.rpg-notebook-lines`).
**Fix (style.css:2597):**
Added `width: 100%;` to `.rpg-notebook-line`
**How it works:**
- `.rpg-notebook-lines` has `flex: 1` → fills vertical space
- `.rpg-notebook-line` now has `width: 100%` → fills horizontal space
- `.rpg-event-text` has `flex: 1` → expands to fill remaining space after bullet
- `.rpg-bullet` stays at natural size
**Result:**
Event lines now stretch to use full widget width:
- Content fills horizontally from left to right
- Event text wraps properly using full available width
- No wasted space on the right
- Widget looks properly sized, not like a "little calendar thing"
**Before:**
Event lines shrink to content width → narrow appearance with unused space
**After:**
Event lines stretch to 100% width → full-width content utilizing all available space
Fixed CSS flexbox issue where Recent Events widget only used ~20-30% of its
allocated 2×2 grid space. Content was cramped at bottom with large empty space above.
**Root Cause:**
- `.rpg-events-widget` missing height and flex properties
- `.rpg-notebook-lines` (event container) not expanding to fill available space
- Widget only expanded to fit content, not allocated grid cell
**Changes (style.css):**
1. `.rpg-events-widget` (lines 2516-2517):
- Added `height: 100%` to fill parent container
- Added `flex: 1` to participate in flex layout properly
2. `.rpg-notebook-lines` (lines 2588-2589):
- Added `flex: 1` to expand and fill remaining vertical space
- Added `min-height: 0` to prevent flex item overflow
**Result:**
- Widget now properly fills full 2×2 grid allocation
- Events have proper breathing room and spacing
- Notebook aesthetic preserved with better proportions
- Works correctly at any size (2×1, 2×2, 3×3, etc.)
**Before:** ~134px content in ~300-400px space = 30-40% utilization
**After:** Content fills full allocated space with proper distribution
Implemented Smart Hybrid Parser to handle virtually any fantasy or real-world scenario
while maintaining backward compatibility with existing comma-separated formats.
**Date Parsing Enhancement (infoBoxWidgets.js, lines 43-62):**
- Added conditional parsing: structured (comma-separated) vs unstructured
- Structured: "Tuesday, 15 January, 2024" → weekday/month/year split
- Unstructured: "3rd Day of Ninth Moon Year of Dragon" → full text in month field
- Handles: Fantasy calendars, ISO dates (2024-01-15), prose, stardates
**Weather Parsing Enhancement (infoBoxWidgets.js, lines 84-120):**
- JOIN remaining comma parts instead of taking only 2nd part
- Fixes: "🌧️, Heavy rain, flooding, winds" → preserves full forecast
- Added emoji prefix detection for non-comma formats
- Handles prose weather: "The air crackles with magical energy"
- Graceful fallback: no emoji → text-only display
**formatWeather Enhancement (sceneInfoWidget.js, lines 65-102):**
- Added no-emoji handling (display forecast only)
- Expanded symbol validation: custom symbols (+++, ***, ##)
- Symbol regex: /^[+*#~\-=_]+$/ for weather symbols
- Text-as-emoji handling: combines text with forecast gracefully
**formatLocation Enhancement (sceneInfoWidget.js, lines 126-148):**
- Changed to split on FIRST comma only (using indexOf)
- Preserves all remaining text after first comma as label
- Fixes: "The Winding Stair, Third Floor, East Wing, Palace" → keeps full context
- Still preserves hyphens in names (Seol Yi-hwan)
**CSS Text Wrapping (style.css, lines 2716-2745):**
- Removed white-space: nowrap restriction
- Added -webkit-line-clamp: 3 for values (2-3 line wrap)
- Added -webkit-line-clamp: 2 for labels
- Added word-wrap and overflow-wrap for long words
- Text now wraps gracefully instead of truncating prematurely
**Backward Compatibility:**
✅ Existing formats continue to work perfectly
✅ "Tuesday, 15 January, 2024" still parses as structured
✅ "🌤️, Partly cloudy" still displays with emoji
✅ "Location, City" still splits correctly
**New Format Support:**
✅ Fantasy: "3rd Day of the Ninth Moon Year of the Azure Dragon"
✅ ISO: "2024-01-15"
✅ Prose: "The third day after the full moon"
✅ Stardates: "Stardate 47634.44"
✅ Weather prose: "The air crackles with magical energy"
✅ Weather symbols: "+++, Heavy rainfall"
✅ Complex locations: "Building A, Floor 3, Room 101, Campus"
✅ Hyphenated names: "Seol Yi-hwan's Private Quarters"
**Testing Scenarios Covered:**
- Standard comma-separated formats (backward compat)
- Fantasy calendars without commas
- ISO date formats
- Prose descriptions for date/weather
- Stardates and custom time systems
- Weather symbols instead of emoji
- Multi-part weather forecasts
- Long multi-part locations
- Hyphenated character names
Result: Widget now handles ANY user-defined format while maintaining
visual polish and backward compatibility.
Fixed sizing issues where Scene Info widget overflowed its container.
Problems fixed:
- Removed unnecessary .rpg-dashboard-widget wrapper
- Grid now fills container with height: 100%
- Reduced padding from 1rem → 0.375rem
- Reduced gaps from 0.75rem → 0.375rem
- Reduced item padding from 0.75rem → 0.375rem
- Reduced icon size from 1.5rem → 1.125rem
- Reduced font sizes:
- Value: 1.125rem → 0.875rem
- Label: 0.8125rem → 0.6875rem
- Location value: 1rem → 0.8125rem
- Added text-overflow: ellipsis for long values
- Added min-height: 0 and overflow: hidden
Now follows same sizing pattern as other widgets (userInfo, userStats):
- Direct container without wrapper
- height/width: 100% to fill available space
- Compact padding and gaps
- Responsive font scaling
- Text truncation for overflow
Widget now fits properly in 2x2 grid space.
Complete redesign of Scene Info widget following UX best practices:
BEFORE:
- Tab-based interface with 5 separate views
- Only 1 data point visible at a time (poor scannability)
- Size: 2×3 (oversized, wasted vertical space)
- Didn't fit in desktop side panel
- Poor information density
AFTER:
- Grid-based layout showing all 5 data points simultaneously
- High information density and scannability
- Compact size: 2×2 (reduced from 2×3)
- Inspired by Apple Widgets / Material Design patterns
- Mobile-responsive with breakpoints at 1000px and 340px
- Zero interaction needed - all data visible at once
Changes:
- sceneInfoWidget.js: Complete rewrite (390→309 lines)
- Removed tab logic and state management
- Added data formatting helpers (formatDate, formatTime, etc.)
- Grid HTML structure with semantic CSS classes
- Maintained inline editing for all fields
- Simplified configuration
- style.css: Added comprehensive grid styling (lines 2647-2811)
- CSS Grid layout with named areas
- Responsive typography and spacing
- Hover states and focus styles
- 2 mobile breakpoints for optimal scaling
- defaultLayout.js: Updated Scene Info widget
- Changed height: 3→2 rows
- Adjusted Y positions for widgets below
- Simplified config (removed view selection)
Design Principles:
- All information visible simultaneously (zero interaction)
- High scannability for quick information gathering
- Proper information density for simple data points
- Grid structure: 2 columns, 3 rows (location full-width header)
- Mobile-first responsive design
Layout:
┌─────────────────────────────────┐
│ 📍 Location │
├──────────────────┬──────────────┤
│ 📅 Date │ 🕐 Time │
├──────────────────┼──────────────┤
│ 🌤️ Weather │ 🌡️ Temp │
└──────────────────┴──────────────┘