feat(dashboard): implement smart widget scaling and improved auto-layout

- Add resetWidgetSizesToDefault() to reset all widgets to default sizes before auto-arrange/reset
- Implement continuous expansion algorithm that fills available space up to maxAutoSize limits
- Add visible height detection to prevent widgets expanding beyond viewport (no forced scroll)
- Update all widget defaultSize and maxAutoSize for optimal 1x1 compact layouts
  - Info widgets (calendar, weather, temp, clock): 1x1 default, 1x2 max
  - Location: 2x2 max (was 3x3)
  - Characters: 3x5 max, moved to 'scene' category (eliminates Social tab)
  - User Info: 2x1 max (prevents expansion)
  - User Mood: 1x1 default and max (compact top-right placement)
  - User Attributes: 3x5 max (fills bottom space)
  - User Stats: 3x3 max
- Fix CSS scaling for 1x1 widgets
  - Replace viewport-based units with fixed rem values
  - Reduce icon/graphic sizes to fit with visible text
  - Add explicit gaps and padding for consistent spacing
  - Set line-height: 1 to prevent text overflow
- Reorganize default layout
  - Status tab: User Info (2x1) + Mood (1x1 top right) + Stats + Attributes
  - Scene tab: Info widgets (1x1) + Location + Characters (all on one tab)
  - Inventory tab: Full inventory widget

Auto-arrange and reset now properly size widgets to defaults and expand to fill
available space without exceeding visible area.
This commit is contained in:
Lucas 'Paperboy' Rose-Winters
2025-10-23 22:08:04 +11:00
parent f61e6390fb
commit 3dd7b017a6
10 changed files with 146 additions and 74 deletions
+37
View File
@@ -1183,6 +1183,15 @@ export class DashboardManager {
await this.persistence.resetToDefault(this.defaultLayout); await this.persistence.resetToDefault(this.defaultLayout);
this.applyDashboardConfig(this.defaultLayout); this.applyDashboardConfig(this.defaultLayout);
// Reset all widgets to default sizes
const allWidgets = [];
this.dashboard.tabs.forEach(tab => {
if (tab.widgets && tab.widgets.length > 0) {
allWidgets.push(...tab.widgets);
}
});
this.resetWidgetSizesToDefault(allWidgets);
// Auto-layout each tab to prevent overlap (default positions may have changed) // Auto-layout each tab to prevent overlap (default positions may have changed)
this.dashboard.tabs.forEach(tab => { this.dashboard.tabs.forEach(tab => {
if (tab.widgets && tab.widgets.length > 0) { if (tab.widgets && tab.widgets.length > 0) {
@@ -1212,6 +1221,28 @@ export class DashboardManager {
this.defaultLayout = layout; this.defaultLayout = layout;
} }
/**
* Reset all widgets to their default sizes
* @param {Array} widgets - Widgets to reset
*/
resetWidgetSizesToDefault(widgets) {
let resetCount = 0;
widgets.forEach(widget => {
const definition = this.registry.get(widget.type);
if (definition && definition.defaultSize) {
const oldSize = `${widget.w}x${widget.h}`;
widget.w = definition.defaultSize.w;
widget.h = definition.defaultSize.h;
const newSize = `${widget.w}x${widget.h}`;
if (oldSize !== newSize) {
console.log(`[DashboardManager] Reset ${widget.type} from ${oldSize} to ${newSize}`);
resetCount++;
}
}
});
console.log(`[DashboardManager] Reset ${resetCount} widgets to default sizes`);
}
/** /**
* Auto-layout widgets on current tab to efficiently use all available space * Auto-layout widgets on current tab to efficiently use all available space
* *
@@ -1221,6 +1252,7 @@ export class DashboardManager {
* *
* @param {Object} options - Layout options * @param {Object} options - Layout options
* @param {boolean} [options.preferFullWidth=true] - Prefer full-width widgets when possible * @param {boolean} [options.preferFullWidth=true] - Prefer full-width widgets when possible
* @param {boolean} [options.resetSizes=true] - Reset widgets to default sizes before layout
*/ */
autoLayoutWidgets(options = {}) { autoLayoutWidgets(options = {}) {
console.log('[DashboardManager] Auto-layout widgets requested'); console.log('[DashboardManager] Auto-layout widgets requested');
@@ -1241,6 +1273,11 @@ export class DashboardManager {
console.log(`[DashboardManager] Total widgets to layout: ${allWidgets.length}`); console.log(`[DashboardManager] Total widgets to layout: ${allWidgets.length}`);
// Reset widget sizes to defaults (unless explicitly disabled)
if (options.resetSizes !== false) {
this.resetWidgetSizesToDefault(allWidgets);
}
// Smart category-aware sorting BEFORE auto-layout // Smart category-aware sorting BEFORE auto-layout
const widgetsToLayout = this.sortWidgetsByCategory(allWidgets); const widgetsToLayout = this.sortWidgetsByCategory(allWidgets);
+24 -25
View File
@@ -39,7 +39,7 @@ export function generateDefaultDashboard() {
icon: '📊', icon: '📊',
order: 0, order: 0,
widgets: [ widgets: [
// Row 0: User Info (avatar, name, level) // Row 0: User Info (left) + User Mood (top right in 3-col)
{ {
id: 'widget-userinfo', id: 'widget-userinfo',
type: 'userInfo', type: 'userInfo',
@@ -49,6 +49,15 @@ export function generateDefaultDashboard() {
h: 1, h: 1,
config: {} config: {}
}, },
{
id: 'widget-usermood',
type: 'userMood',
x: 2,
y: 0,
w: 1,
h: 1,
config: {}
},
// Row 1-2: User Stats (health/energy bars) // Row 1-2: User Stats (health/energy bars)
{ {
id: 'widget-userstats', id: 'widget-userstats',
@@ -61,22 +70,12 @@ export function generateDefaultDashboard() {
statBarGradient: true statBarGradient: true
} }
}, },
// Row 3: User Mood // Row 3-4: User Attributes
{
id: 'widget-usermood',
type: 'userMood',
x: 0,
y: 3,
w: 2,
h: 1,
config: {}
},
// Row 4-5: User Attributes
{ {
id: 'widget-userattributes', id: 'widget-userattributes',
type: 'userAttributes', type: 'userAttributes',
x: 0, x: 0,
y: 4, y: 3,
w: 2, w: 2,
h: 2, h: 2,
config: {} config: {}
@@ -90,14 +89,14 @@ export function generateDefaultDashboard() {
icon: '🌍', icon: '🌍',
order: 1, order: 1,
widgets: [ widgets: [
// Row 0-1: Calendar (left) + Weather (right) // Row 0: Calendar (left) + Weather (right)
{ {
id: 'widget-calendar', id: 'widget-calendar',
type: 'calendar', type: 'calendar',
x: 0, x: 0,
y: 0, y: 0,
w: 1, w: 1,
h: 2, h: 1,
config: {} config: {}
}, },
{ {
@@ -106,19 +105,19 @@ export function generateDefaultDashboard() {
x: 1, x: 1,
y: 0, y: 0,
w: 1, w: 1,
h: 2, h: 1,
config: { config: {
compact: false compact: false
} }
}, },
// Row 2-3: Temperature (left) + Clock (right) // Row 1: Temperature (left) + Clock (right)
{ {
id: 'widget-temperature', id: 'widget-temperature',
type: 'temperature', type: 'temperature',
x: 0, x: 0,
y: 2, y: 1,
w: 1, w: 1,
h: 2, h: 1,
config: { config: {
unit: 'celsius' unit: 'celsius'
} }
@@ -127,29 +126,29 @@ export function generateDefaultDashboard() {
id: 'widget-clock', id: 'widget-clock',
type: 'clock', type: 'clock',
x: 1, x: 1,
y: 2, y: 1,
w: 1, w: 1,
h: 2, h: 1,
config: { config: {
format: 'digital' format: 'digital'
} }
}, },
// Row 4-5: Location (full width) // Row 2-3: Location (full width)
{ {
id: 'widget-location', id: 'widget-location',
type: 'location', type: 'location',
x: 0, x: 0,
y: 4, y: 2,
w: 2, w: 2,
h: 2, h: 2,
config: {} config: {}
}, },
// Row 6-8: Present Characters (full width, will expand with auto-layout) // Row 4-6: Present Characters (full width, will expand with auto-layout)
{ {
id: 'widget-presentchars', id: 'widget-presentchars',
type: 'presentCharacters', type: 'presentCharacters',
x: 0, x: 0,
y: 6, y: 4,
w: 2, w: 2,
h: 3, h: 3,
config: { config: {
+38 -12
View File
@@ -435,10 +435,22 @@ export class GridEngine {
const preserveOrder = options.preserveOrder || false; const preserveOrder = options.preserveOrder || false;
// Calculate maximum visible rows based on container height
let maxVisibleRows = 100; // Fallback
if (this.container) {
const containerHeight = this.container.clientHeight; // pixels
const rootFontSize = parseFloat(getComputedStyle(document.documentElement).fontSize); // px per rem
const containerHeightRem = containerHeight / rootFontSize;
const rowHeightWithGap = this.rowHeight + this.gap;
maxVisibleRows = Math.floor(containerHeightRem / rowHeightWithGap);
console.log('[GridEngine] Container height:', containerHeight + 'px', '=', containerHeightRem.toFixed(2) + 'rem', '→', maxVisibleRows, 'rows');
}
console.log('[GridEngine] Auto-layout started:', { console.log('[GridEngine] Auto-layout started:', {
widgetCount: widgets.length, widgetCount: widgets.length,
columns: this.columns, columns: this.columns,
preserveOrder preserveOrder,
maxVisibleRows
}); });
// Sort widgets (or preserve input order for category-aware layout) // Sort widgets (or preserve input order for category-aware layout)
@@ -586,8 +598,8 @@ export class GridEngine {
return definition.maxAutoSize; return definition.maxAutoSize;
} }
} }
// Default max size if not specified (flexible expansion) // Default max size if not specified (conservative expansion)
return { w: this.columns, h: 10 }; return { w: this.columns, h: 3 };
}; };
sortedForExpand.forEach(widget => { sortedForExpand.forEach(widget => {
@@ -595,9 +607,15 @@ export class GridEngine {
const originalW = widget.w; const originalW = widget.w;
const originalH = widget.h; const originalH = widget.h;
// Try expanding height first (fills vertical gaps) // Try expanding height first (fills vertical gaps) - keep trying until maxSize or collision
let expandedH = false; let expandedH = false;
for (let tryH = originalH + 1; tryH <= Math.min(maxSize.h, originalH + 3); tryH++) { for (let tryH = originalH + 1; tryH <= maxSize.h; tryH++) {
// Check if expansion would go beyond visible area
if (widget.y + tryH > maxVisibleRows) {
console.log(`[GridEngine] ${widget.id} cannot expand to h=${tryH} (would exceed visible area: row ${widget.y + tryH} > ${maxVisibleRows})`);
break;
}
// Clear current position // Clear current position
for (let row = widget.y; row < widget.y + widget.h; row++) { for (let row = widget.y; row < widget.y + widget.h; row++) {
for (let col = widget.x; col < widget.x + widget.w; col++) { for (let col = widget.x; col < widget.x + widget.w; col++) {
@@ -611,15 +629,19 @@ export class GridEngine {
markOccupied(widget, widget.x, widget.y, widget.w, tryH); markOccupied(widget, widget.x, widget.y, widget.w, tryH);
expandedH = true; expandedH = true;
expandedCount++; expandedCount++;
console.log(`[GridEngine] Expanded ${widget.id} height: ${originalH}${tryH}`); // Continue trying to expand further
break;
} else { } else {
// Re-mark original and try next size // Hit a collision, stop expanding height
markOccupied(widget, widget.x, widget.y, widget.w, widget.h); markOccupied(widget, widget.x, widget.y, widget.w, widget.h);
break;
} }
} }
// Try expanding width (fills horizontal gaps) if (expandedH) {
console.log(`[GridEngine] Expanded ${widget.id} height: ${originalH}${widget.h}`);
}
// Try expanding width (fills horizontal gaps) - keep trying until maxSize or collision
let expandedW = false; let expandedW = false;
for (let tryW = originalW + 1; tryW <= Math.min(maxSize.w, this.columns); tryW++) { for (let tryW = originalW + 1; tryW <= Math.min(maxSize.w, this.columns); tryW++) {
// Clear current position // Clear current position
@@ -635,14 +657,18 @@ export class GridEngine {
markOccupied(widget, widget.x, widget.y, tryW, widget.h); markOccupied(widget, widget.x, widget.y, tryW, widget.h);
expandedW = true; expandedW = true;
expandedCount++; expandedCount++;
console.log(`[GridEngine] Expanded ${widget.id} width: ${originalW}${tryW}`); // Continue trying to expand further
break;
} else { } else {
// Re-mark original and try next size // Hit a collision, stop expanding width
markOccupied(widget, widget.x, widget.y, widget.w, widget.h); markOccupied(widget, widget.x, widget.y, widget.w, widget.h);
break;
} }
} }
if (expandedW) {
console.log(`[GridEngine] Expanded ${widget.id} width: ${originalW}${widget.w}`);
}
if (!expandedH && !expandedW) { if (!expandedH && !expandedW) {
// Widget couldn't expand - ensure it's still marked in grid // Widget couldn't expand - ensure it's still marked in grid
markOccupied(widget, widget.x, widget.y, widget.w, widget.h); markOccupied(widget, widget.x, widget.y, widget.w, widget.h);
+13 -13
View File
@@ -192,9 +192,9 @@ export function registerCalendarWidget(registry, dependencies) {
icon: '📅', icon: '📅',
description: 'Date, weekday, month, and year display', description: 'Date, weekday, month, and year display',
category: 'scene', category: 'scene',
minSize: { w: 1, h: 2 }, minSize: { w: 1, h: 1 },
defaultSize: { w: 1, h: 2 }, defaultSize: { w: 1, h: 1 },
maxAutoSize: { w: 2, h: 3 }, // Max size for auto-arrange expansion maxAutoSize: { w: 1, h: 2 }, // Max size for auto-arrange expansion
requiresSchema: false, requiresSchema: false,
render(container, config = {}) { render(container, config = {}) {
@@ -280,9 +280,9 @@ export function registerWeatherWidget(registry, dependencies) {
name: 'Weather', name: 'Weather',
icon: '🌤️', icon: '🌤️',
description: 'Weather emoji and forecast', description: 'Weather emoji and forecast',
minSize: { w: 1, h: 2 }, minSize: { w: 1, h: 1 },
defaultSize: { w: 1, h: 2 }, defaultSize: { w: 1, h: 1 },
maxAutoSize: { w: 2, h: 3 }, // Max size for auto-arrange expansion maxAutoSize: { w: 1, h: 2 }, // Max size for auto-arrange expansion
requiresSchema: false, requiresSchema: false,
render(container, config = {}) { render(container, config = {}) {
@@ -314,9 +314,9 @@ export function registerTemperatureWidget(registry, dependencies) {
name: 'Temperature', name: 'Temperature',
icon: '🌡️', icon: '🌡️',
description: 'Temperature display with thermometer', description: 'Temperature display with thermometer',
minSize: { w: 1, h: 2 }, minSize: { w: 1, h: 1 },
defaultSize: { w: 1, h: 2 }, defaultSize: { w: 1, h: 1 },
maxAutoSize: { w: 2, h: 3 }, // Max size for auto-arrange expansion maxAutoSize: { w: 1, h: 2 }, // Max size for auto-arrange expansion
requiresSchema: false, requiresSchema: false,
render(container, config = {}) { render(container, config = {}) {
@@ -355,9 +355,9 @@ export function registerClockWidget(registry, dependencies) {
name: 'Clock', name: 'Clock',
icon: '🕐', icon: '🕐',
description: 'Analog clock with time display', description: 'Analog clock with time display',
minSize: { w: 1, h: 2 }, minSize: { w: 1, h: 1 },
defaultSize: { w: 1, h: 2 }, defaultSize: { w: 1, h: 1 },
maxAutoSize: { w: 2, h: 3 }, // Max size for auto-arrange expansion maxAutoSize: { w: 1, h: 2 }, // Max size for auto-arrange expansion
requiresSchema: false, requiresSchema: false,
render(container, config = {}) { render(container, config = {}) {
@@ -407,7 +407,7 @@ export function registerLocationWidget(registry, dependencies) {
description: 'Map with location display', description: 'Map with location display',
minSize: { w: 1, h: 2 }, minSize: { w: 1, h: 2 },
defaultSize: { w: 2, h: 2 }, defaultSize: { w: 2, h: 2 },
maxAutoSize: { w: 3, h: 3 }, // Max size for auto-arrange expansion maxAutoSize: { w: 2, h: 2 }, // Max size for auto-arrange expansion
requiresSchema: false, requiresSchema: false,
render(container, config = {}) { render(container, config = {}) {
@@ -235,10 +235,10 @@ export function registerPresentCharactersWidget(registry, dependencies) {
name: 'Present Characters', name: 'Present Characters',
icon: '👥', icon: '👥',
description: 'Character cards with avatars, traits, and relationships', description: 'Character cards with avatars, traits, and relationships',
category: 'social', category: 'scene',
minSize: { w: 2, h: 2 }, minSize: { w: 2, h: 2 },
defaultSize: { w: 2, h: 3 }, defaultSize: { w: 2, h: 3 },
maxAutoSize: { w: 3, h: 6 }, // Max size for auto-arrange expansion (can expand significantly) maxAutoSize: { w: 3, h: 5 }, // Max size for auto-arrange expansion
requiresSchema: false, requiresSchema: false,
render(container, config = {}) { render(container, config = {}) {
@@ -33,6 +33,7 @@ export function registerUserAttributesWidget(registry, dependencies) {
category: 'user', category: 'user',
minSize: { w: 2, h: 2 }, minSize: { w: 2, h: 2 },
defaultSize: { w: 2, h: 2 }, defaultSize: { w: 2, h: 2 },
maxAutoSize: { w: 3, h: 5 }, // Max size for auto-arrange expansion
requiresSchema: false, requiresSchema: false,
/** /**
@@ -37,6 +37,7 @@ export function registerUserInfoWidget(registry, dependencies) {
category: 'user', category: 'user',
minSize: { w: 1, h: 1 }, minSize: { w: 1, h: 1 },
defaultSize: { w: 2, h: 1 }, defaultSize: { w: 2, h: 1 },
maxAutoSize: { w: 2, h: 1 }, // Max size for auto-arrange expansion
requiresSchema: false, requiresSchema: false,
/** /**
@@ -29,7 +29,8 @@ export function registerUserMoodWidget(registry, dependencies) {
description: 'Mood emoji and active conditions', description: 'Mood emoji and active conditions',
category: 'user', category: 'user',
minSize: { w: 1, h: 1 }, minSize: { w: 1, h: 1 },
defaultSize: { w: 2, h: 1 }, defaultSize: { w: 1, h: 1 },
maxAutoSize: { w: 1, h: 1 }, // Max size for auto-arrange expansion - stays compact in top right
requiresSchema: false, requiresSchema: false,
/** /**
@@ -34,6 +34,7 @@ export function registerUserStatsWidget(registry, dependencies) {
category: 'user', category: 'user',
minSize: { w: 1, h: 2 }, minSize: { w: 1, h: 2 },
defaultSize: { w: 2, h: 2 }, defaultSize: { w: 2, h: 2 },
maxAutoSize: { w: 3, h: 3 }, // Max size for auto-arrange expansion
requiresSchema: false, requiresSchema: false,
/** /**
+27 -21
View File
@@ -1400,7 +1400,7 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
.rpg-calendar-top { .rpg-calendar-top {
background: var(--rpg-highlight); background: var(--rpg-highlight);
color: var(--rpg-bg); color: var(--rpg-bg);
font-size: clamp(0.6rem, 0.7rem, 0.8rem); font-size: 0.65rem;
font-weight: bold; font-weight: bold;
padding: 0.125em 0.375em; padding: 0.125em 0.375em;
border-radius: 3px 3px 0 0; border-radius: 3px 3px 0 0;
@@ -1412,9 +1412,9 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
.rpg-calendar-day { .rpg-calendar-day {
background: rgba(255, 255, 255, 0.1); background: rgba(255, 255, 255, 0.1);
color: var(--rpg-text); color: var(--rpg-text);
font-size: clamp(1.5rem, 2.5rem, 3.5rem); font-size: 1.8rem;
font-weight: bold; font-weight: bold;
padding: 0.25em; padding: 0.1em;
width: 100%; width: 100%;
text-align: center; text-align: center;
border: 2px solid var(--rpg-highlight); border: 2px solid var(--rpg-highlight);
@@ -1427,7 +1427,7 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
} }
.rpg-calendar-year { .rpg-calendar-year {
font-size: clamp(0.6rem, 0.7rem, 0.8rem); font-size: 0.55rem;
color: var(--rpg-text); color: var(--rpg-text);
opacity: 0.7; opacity: 0.7;
margin-top: 0.062em; margin-top: 0.062em;
@@ -1439,19 +1439,21 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
height: 100%; height: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-around; justify-content: center;
align-items: center; align-items: center;
padding: 0.5rem; padding: 0.25rem;
gap: 0.2rem;
} }
.rpg-weather-icon { .rpg-weather-icon {
font-size: clamp(2rem, 8vh, 4rem); font-size: 2rem;
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.5)); filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.5));
flex-shrink: 0; flex-shrink: 1;
line-height: 1;
} }
.rpg-weather-forecast { .rpg-weather-forecast {
font-size: clamp(0.7rem, 0.9rem, 1.1rem); font-size: 0.65rem;
text-align: center; text-align: center;
margin: 0; margin: 0;
font-weight: 600; font-weight: 600;
@@ -1477,13 +1479,14 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
gap: 0.5rem; padding: 0.25rem;
gap: 0.2rem;
} }
.rpg-thermometer { .rpg-thermometer {
position: relative; position: relative;
width: clamp(1.5rem, 2rem, 3rem); width: 1.2rem;
height: clamp(4rem, 60%, 8rem); height: 2.5rem;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
@@ -1522,11 +1525,12 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
} }
.rpg-temp-value { .rpg-temp-value {
font-size: clamp(0.7rem, 0.9rem, 1.1rem); font-size: 0.65rem;
font-weight: bold; font-weight: bold;
color: var(--rpg-text); color: var(--rpg-text);
text-align: center; text-align: center;
flex-shrink: 0; flex-shrink: 0;
line-height: 1;
} }
/* Clock Widget */ /* Clock Widget */
@@ -1534,18 +1538,19 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
height: 100%; height: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-around; justify-content: center;
align-items: center; align-items: center;
gap: 0.5rem; padding: 0.25rem;
gap: 0.2rem;
} }
.rpg-clock { .rpg-clock {
width: clamp(3rem, 60%, 6rem); width: 2.5rem;
height: clamp(3rem, 60%, 6rem); height: 2.5rem;
aspect-ratio: 1 / 1; aspect-ratio: 1 / 1;
border-radius: 50%; border-radius: 50%;
background: rgba(0, 0, 0, 0.4); background: rgba(0, 0, 0, 0.4);
border: 3px solid var(--rpg-border); border: 2px solid var(--rpg-border);
box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.5); box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.5);
position: relative; position: relative;
flex-shrink: 1; flex-shrink: 1;
@@ -1593,10 +1598,11 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
} }
.rpg-time-value { .rpg-time-value {
font-size: clamp(0.7rem, 0.9rem, 1.1rem); font-size: 0.65rem;
font-weight: bold; font-weight: bold;
color: var(--rpg-text); color: var(--rpg-text);
flex-shrink: 0; flex-shrink: 0;
line-height: 1;
} }
/* Location Widget - Map */ /* Location Widget - Map */
@@ -1623,7 +1629,7 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
} }
.rpg-map-marker { .rpg-map-marker {
font-size: clamp(1.5rem, 4vh, 3rem); font-size: 2rem;
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8)); filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8));
animation: markerPulse 2s ease-in-out infinite; animation: markerPulse 2s ease-in-out infinite;
} }
@@ -1634,7 +1640,7 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
} }
.rpg-location-text { .rpg-location-text {
font-size: clamp(0.7rem, 0.9rem, 1.1rem); font-size: 0.75rem;
font-weight: bold; font-weight: bold;
color: var(--rpg-text); color: var(--rpg-text);
text-align: center; text-align: center;