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:
@@ -1183,6 +1183,15 @@ export class DashboardManager {
|
||||
await this.persistence.resetToDefault(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)
|
||||
this.dashboard.tabs.forEach(tab => {
|
||||
if (tab.widgets && tab.widgets.length > 0) {
|
||||
@@ -1212,6 +1221,28 @@ export class DashboardManager {
|
||||
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
|
||||
*
|
||||
@@ -1221,6 +1252,7 @@ export class DashboardManager {
|
||||
*
|
||||
* @param {Object} options - Layout options
|
||||
* @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 = {}) {
|
||||
console.log('[DashboardManager] Auto-layout widgets requested');
|
||||
@@ -1241,6 +1273,11 @@ export class DashboardManager {
|
||||
|
||||
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
|
||||
const widgetsToLayout = this.sortWidgetsByCategory(allWidgets);
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ export function generateDefaultDashboard() {
|
||||
icon: '📊',
|
||||
order: 0,
|
||||
widgets: [
|
||||
// Row 0: User Info (avatar, name, level)
|
||||
// Row 0: User Info (left) + User Mood (top right in 3-col)
|
||||
{
|
||||
id: 'widget-userinfo',
|
||||
type: 'userInfo',
|
||||
@@ -49,6 +49,15 @@ export function generateDefaultDashboard() {
|
||||
h: 1,
|
||||
config: {}
|
||||
},
|
||||
{
|
||||
id: 'widget-usermood',
|
||||
type: 'userMood',
|
||||
x: 2,
|
||||
y: 0,
|
||||
w: 1,
|
||||
h: 1,
|
||||
config: {}
|
||||
},
|
||||
// Row 1-2: User Stats (health/energy bars)
|
||||
{
|
||||
id: 'widget-userstats',
|
||||
@@ -61,22 +70,12 @@ export function generateDefaultDashboard() {
|
||||
statBarGradient: true
|
||||
}
|
||||
},
|
||||
// Row 3: User Mood
|
||||
{
|
||||
id: 'widget-usermood',
|
||||
type: 'userMood',
|
||||
x: 0,
|
||||
y: 3,
|
||||
w: 2,
|
||||
h: 1,
|
||||
config: {}
|
||||
},
|
||||
// Row 4-5: User Attributes
|
||||
// Row 3-4: User Attributes
|
||||
{
|
||||
id: 'widget-userattributes',
|
||||
type: 'userAttributes',
|
||||
x: 0,
|
||||
y: 4,
|
||||
y: 3,
|
||||
w: 2,
|
||||
h: 2,
|
||||
config: {}
|
||||
@@ -90,14 +89,14 @@ export function generateDefaultDashboard() {
|
||||
icon: '🌍',
|
||||
order: 1,
|
||||
widgets: [
|
||||
// Row 0-1: Calendar (left) + Weather (right)
|
||||
// Row 0: Calendar (left) + Weather (right)
|
||||
{
|
||||
id: 'widget-calendar',
|
||||
type: 'calendar',
|
||||
x: 0,
|
||||
y: 0,
|
||||
w: 1,
|
||||
h: 2,
|
||||
h: 1,
|
||||
config: {}
|
||||
},
|
||||
{
|
||||
@@ -106,19 +105,19 @@ export function generateDefaultDashboard() {
|
||||
x: 1,
|
||||
y: 0,
|
||||
w: 1,
|
||||
h: 2,
|
||||
h: 1,
|
||||
config: {
|
||||
compact: false
|
||||
}
|
||||
},
|
||||
// Row 2-3: Temperature (left) + Clock (right)
|
||||
// Row 1: Temperature (left) + Clock (right)
|
||||
{
|
||||
id: 'widget-temperature',
|
||||
type: 'temperature',
|
||||
x: 0,
|
||||
y: 2,
|
||||
y: 1,
|
||||
w: 1,
|
||||
h: 2,
|
||||
h: 1,
|
||||
config: {
|
||||
unit: 'celsius'
|
||||
}
|
||||
@@ -127,29 +126,29 @@ export function generateDefaultDashboard() {
|
||||
id: 'widget-clock',
|
||||
type: 'clock',
|
||||
x: 1,
|
||||
y: 2,
|
||||
y: 1,
|
||||
w: 1,
|
||||
h: 2,
|
||||
h: 1,
|
||||
config: {
|
||||
format: 'digital'
|
||||
}
|
||||
},
|
||||
// Row 4-5: Location (full width)
|
||||
// Row 2-3: Location (full width)
|
||||
{
|
||||
id: 'widget-location',
|
||||
type: 'location',
|
||||
x: 0,
|
||||
y: 4,
|
||||
y: 2,
|
||||
w: 2,
|
||||
h: 2,
|
||||
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',
|
||||
type: 'presentCharacters',
|
||||
x: 0,
|
||||
y: 6,
|
||||
y: 4,
|
||||
w: 2,
|
||||
h: 3,
|
||||
config: {
|
||||
|
||||
@@ -435,10 +435,22 @@ export class GridEngine {
|
||||
|
||||
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:', {
|
||||
widgetCount: widgets.length,
|
||||
columns: this.columns,
|
||||
preserveOrder
|
||||
preserveOrder,
|
||||
maxVisibleRows
|
||||
});
|
||||
|
||||
// Sort widgets (or preserve input order for category-aware layout)
|
||||
@@ -586,8 +598,8 @@ export class GridEngine {
|
||||
return definition.maxAutoSize;
|
||||
}
|
||||
}
|
||||
// Default max size if not specified (flexible expansion)
|
||||
return { w: this.columns, h: 10 };
|
||||
// Default max size if not specified (conservative expansion)
|
||||
return { w: this.columns, h: 3 };
|
||||
};
|
||||
|
||||
sortedForExpand.forEach(widget => {
|
||||
@@ -595,9 +607,15 @@ export class GridEngine {
|
||||
const originalW = widget.w;
|
||||
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;
|
||||
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
|
||||
for (let row = widget.y; row < widget.y + widget.h; row++) {
|
||||
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);
|
||||
expandedH = true;
|
||||
expandedCount++;
|
||||
console.log(`[GridEngine] Expanded ${widget.id} height: ${originalH} → ${tryH}`);
|
||||
break;
|
||||
// Continue trying to expand further
|
||||
} else {
|
||||
// Re-mark original and try next size
|
||||
// Hit a collision, stop expanding height
|
||||
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;
|
||||
for (let tryW = originalW + 1; tryW <= Math.min(maxSize.w, this.columns); tryW++) {
|
||||
// Clear current position
|
||||
@@ -635,14 +657,18 @@ export class GridEngine {
|
||||
markOccupied(widget, widget.x, widget.y, tryW, widget.h);
|
||||
expandedW = true;
|
||||
expandedCount++;
|
||||
console.log(`[GridEngine] Expanded ${widget.id} width: ${originalW} → ${tryW}`);
|
||||
break;
|
||||
// Continue trying to expand further
|
||||
} else {
|
||||
// Re-mark original and try next size
|
||||
// Hit a collision, stop expanding width
|
||||
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) {
|
||||
// Widget couldn't expand - ensure it's still marked in grid
|
||||
markOccupied(widget, widget.x, widget.y, widget.w, widget.h);
|
||||
|
||||
@@ -192,9 +192,9 @@ export function registerCalendarWidget(registry, dependencies) {
|
||||
icon: '📅',
|
||||
description: 'Date, weekday, month, and year display',
|
||||
category: 'scene',
|
||||
minSize: { w: 1, h: 2 },
|
||||
defaultSize: { w: 1, h: 2 },
|
||||
maxAutoSize: { w: 2, h: 3 }, // Max size for auto-arrange expansion
|
||||
minSize: { w: 1, h: 1 },
|
||||
defaultSize: { w: 1, h: 1 },
|
||||
maxAutoSize: { w: 1, h: 2 }, // Max size for auto-arrange expansion
|
||||
requiresSchema: false,
|
||||
|
||||
render(container, config = {}) {
|
||||
@@ -280,9 +280,9 @@ export function registerWeatherWidget(registry, dependencies) {
|
||||
name: 'Weather',
|
||||
icon: '🌤️',
|
||||
description: 'Weather emoji and forecast',
|
||||
minSize: { w: 1, h: 2 },
|
||||
defaultSize: { w: 1, h: 2 },
|
||||
maxAutoSize: { w: 2, h: 3 }, // Max size for auto-arrange expansion
|
||||
minSize: { w: 1, h: 1 },
|
||||
defaultSize: { w: 1, h: 1 },
|
||||
maxAutoSize: { w: 1, h: 2 }, // Max size for auto-arrange expansion
|
||||
requiresSchema: false,
|
||||
|
||||
render(container, config = {}) {
|
||||
@@ -314,9 +314,9 @@ export function registerTemperatureWidget(registry, dependencies) {
|
||||
name: 'Temperature',
|
||||
icon: '🌡️',
|
||||
description: 'Temperature display with thermometer',
|
||||
minSize: { w: 1, h: 2 },
|
||||
defaultSize: { w: 1, h: 2 },
|
||||
maxAutoSize: { w: 2, h: 3 }, // Max size for auto-arrange expansion
|
||||
minSize: { w: 1, h: 1 },
|
||||
defaultSize: { w: 1, h: 1 },
|
||||
maxAutoSize: { w: 1, h: 2 }, // Max size for auto-arrange expansion
|
||||
requiresSchema: false,
|
||||
|
||||
render(container, config = {}) {
|
||||
@@ -355,9 +355,9 @@ export function registerClockWidget(registry, dependencies) {
|
||||
name: 'Clock',
|
||||
icon: '🕐',
|
||||
description: 'Analog clock with time display',
|
||||
minSize: { w: 1, h: 2 },
|
||||
defaultSize: { w: 1, h: 2 },
|
||||
maxAutoSize: { w: 2, h: 3 }, // Max size for auto-arrange expansion
|
||||
minSize: { w: 1, h: 1 },
|
||||
defaultSize: { w: 1, h: 1 },
|
||||
maxAutoSize: { w: 1, h: 2 }, // Max size for auto-arrange expansion
|
||||
requiresSchema: false,
|
||||
|
||||
render(container, config = {}) {
|
||||
@@ -407,7 +407,7 @@ export function registerLocationWidget(registry, dependencies) {
|
||||
description: 'Map with location display',
|
||||
minSize: { w: 1, 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,
|
||||
|
||||
render(container, config = {}) {
|
||||
|
||||
@@ -235,10 +235,10 @@ export function registerPresentCharactersWidget(registry, dependencies) {
|
||||
name: 'Present Characters',
|
||||
icon: '👥',
|
||||
description: 'Character cards with avatars, traits, and relationships',
|
||||
category: 'social',
|
||||
category: 'scene',
|
||||
minSize: { w: 2, h: 2 },
|
||||
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,
|
||||
|
||||
render(container, config = {}) {
|
||||
|
||||
@@ -33,6 +33,7 @@ export function registerUserAttributesWidget(registry, dependencies) {
|
||||
category: 'user',
|
||||
minSize: { w: 2, h: 2 },
|
||||
defaultSize: { w: 2, h: 2 },
|
||||
maxAutoSize: { w: 3, h: 5 }, // Max size for auto-arrange expansion
|
||||
requiresSchema: false,
|
||||
|
||||
/**
|
||||
|
||||
@@ -37,6 +37,7 @@ export function registerUserInfoWidget(registry, dependencies) {
|
||||
category: 'user',
|
||||
minSize: { w: 1, h: 1 },
|
||||
defaultSize: { w: 2, h: 1 },
|
||||
maxAutoSize: { w: 2, h: 1 }, // Max size for auto-arrange expansion
|
||||
requiresSchema: false,
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,7 +29,8 @@ export function registerUserMoodWidget(registry, dependencies) {
|
||||
description: 'Mood emoji and active conditions',
|
||||
category: 'user',
|
||||
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,
|
||||
|
||||
/**
|
||||
|
||||
@@ -34,6 +34,7 @@ export function registerUserStatsWidget(registry, dependencies) {
|
||||
category: 'user',
|
||||
minSize: { w: 1, h: 2 },
|
||||
defaultSize: { w: 2, h: 2 },
|
||||
maxAutoSize: { w: 3, h: 3 }, // Max size for auto-arrange expansion
|
||||
requiresSchema: false,
|
||||
|
||||
/**
|
||||
|
||||
@@ -1400,7 +1400,7 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
|
||||
.rpg-calendar-top {
|
||||
background: var(--rpg-highlight);
|
||||
color: var(--rpg-bg);
|
||||
font-size: clamp(0.6rem, 0.7rem, 0.8rem);
|
||||
font-size: 0.65rem;
|
||||
font-weight: bold;
|
||||
padding: 0.125em 0.375em;
|
||||
border-radius: 3px 3px 0 0;
|
||||
@@ -1412,9 +1412,9 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
|
||||
.rpg-calendar-day {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
color: var(--rpg-text);
|
||||
font-size: clamp(1.5rem, 2.5rem, 3.5rem);
|
||||
font-size: 1.8rem;
|
||||
font-weight: bold;
|
||||
padding: 0.25em;
|
||||
padding: 0.1em;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
border: 2px solid var(--rpg-highlight);
|
||||
@@ -1427,7 +1427,7 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
|
||||
}
|
||||
|
||||
.rpg-calendar-year {
|
||||
font-size: clamp(0.6rem, 0.7rem, 0.8rem);
|
||||
font-size: 0.55rem;
|
||||
color: var(--rpg-text);
|
||||
opacity: 0.7;
|
||||
margin-top: 0.062em;
|
||||
@@ -1439,19 +1439,21 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 0.5rem;
|
||||
padding: 0.25rem;
|
||||
gap: 0.2rem;
|
||||
}
|
||||
|
||||
.rpg-weather-icon {
|
||||
font-size: clamp(2rem, 8vh, 4rem);
|
||||
font-size: 2rem;
|
||||
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.5));
|
||||
flex-shrink: 0;
|
||||
flex-shrink: 1;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.rpg-weather-forecast {
|
||||
font-size: clamp(0.7rem, 0.9rem, 1.1rem);
|
||||
font-size: 0.65rem;
|
||||
text-align: center;
|
||||
margin: 0;
|
||||
font-weight: 600;
|
||||
@@ -1477,13 +1479,14 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
padding: 0.25rem;
|
||||
gap: 0.2rem;
|
||||
}
|
||||
|
||||
.rpg-thermometer {
|
||||
position: relative;
|
||||
width: clamp(1.5rem, 2rem, 3rem);
|
||||
height: clamp(4rem, 60%, 8rem);
|
||||
width: 1.2rem;
|
||||
height: 2.5rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
@@ -1522,11 +1525,12 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
|
||||
}
|
||||
|
||||
.rpg-temp-value {
|
||||
font-size: clamp(0.7rem, 0.9rem, 1.1rem);
|
||||
font-size: 0.65rem;
|
||||
font-weight: bold;
|
||||
color: var(--rpg-text);
|
||||
text-align: center;
|
||||
flex-shrink: 0;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
/* Clock Widget */
|
||||
@@ -1534,18 +1538,19 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
padding: 0.25rem;
|
||||
gap: 0.2rem;
|
||||
}
|
||||
|
||||
.rpg-clock {
|
||||
width: clamp(3rem, 60%, 6rem);
|
||||
height: clamp(3rem, 60%, 6rem);
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
aspect-ratio: 1 / 1;
|
||||
border-radius: 50%;
|
||||
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);
|
||||
position: relative;
|
||||
flex-shrink: 1;
|
||||
@@ -1593,10 +1598,11 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
|
||||
}
|
||||
|
||||
.rpg-time-value {
|
||||
font-size: clamp(0.7rem, 0.9rem, 1.1rem);
|
||||
font-size: 0.65rem;
|
||||
font-weight: bold;
|
||||
color: var(--rpg-text);
|
||||
flex-shrink: 0;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
/* Location Widget - Map */
|
||||
@@ -1623,7 +1629,7 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
|
||||
}
|
||||
|
||||
.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));
|
||||
animation: markerPulse 2s ease-in-out infinite;
|
||||
}
|
||||
@@ -1634,7 +1640,7 @@ body:has(.rpg-panel.rpg-position-left) #sheld {
|
||||
}
|
||||
|
||||
.rpg-location-text {
|
||||
font-size: clamp(0.7rem, 0.9rem, 1.1rem);
|
||||
font-size: 0.75rem;
|
||||
font-weight: bold;
|
||||
color: var(--rpg-text);
|
||||
text-align: center;
|
||||
|
||||
Reference in New Issue
Block a user